diff --git a/TODO b/TODO
index 2d80a431..d9ef2ee2 100644
--- a/TODO
+++ b/TODO
@@ -17,6 +17,7 @@
   cert: turn Info into an enum
   cert/pkey: fingerprints (is there a standard for this?)
   cert: subjectAltName
+  qcaprovider.h -> qca_provider ?
 
 * finish code for APIs:
   cipher - needs to handling padding
diff --git a/include/QtCrypto/QtCrypto b/include/QtCrypto/QtCrypto
new file mode 100644
index 00000000..e9f2249e
--- /dev/null
+++ b/include/QtCrypto/QtCrypto
@@ -0,0 +1 @@
+#include "qca.h"
diff --git a/include/QtCrypto/qca.h b/include/QtCrypto/qca.h
new file mode 100644
index 00000000..c3c1b90e
--- /dev/null
+++ b/include/QtCrypto/qca.h
@@ -0,0 +1,131 @@
+/*
+ * qca.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_H
+#define QCA_H
+
+#include "qca_core.h"
+#include "qca_textfilter.h"
+#include "qca_basic.h"
+#include "qca_publickey.h"
+#include "qca_cert.h"
+#include "qca_securelayer.h"
+
+/**
+   \mainpage %Qt Cryptographic Architecture
+
+   Taking a hint from the similarly-named
+   <a href="http://java.sun.com/j2se/1.4/docs/guide/security/CryptoSpec.html">Java
+   Cryptography Architecture</a>, %QCA aims to provide a
+   straightforward and cross-platform cryptographic API, using Qt
+   datatypes and conventions.  %QCA separates the API from the
+   implementation, using plugins known as Providers.  The advantage
+   of this model is to allow applications to avoid linking to or
+   explicitly depending on any particular cryptographic library.
+   This allows one to easily change or upgrade Provider
+   implementations without even needing to recompile the
+   application!
+
+   %QCA should work everywhere %Qt does, including Windows/Unix/MacOSX.
+
+   \section features Features
+
+   This library provides an easy API for the following features:
+     - Secure byte arrays (QSecureArray)
+     - Arbitrary precision integers (QBigInteger)
+     - Random number generation (QCA::Random)
+     - SSL/TLS (ToDo)
+     - X509 certificate (Cert) (ToDo)
+     - Simple Authentication and Security Layer (SASL) (ToDo)
+     - RSA (ToDo)
+     - Hashing (QCA::Hash)
+         - QCA::SHA0
+         - QCA::SHA1
+         - QCA::MD2
+         - QCA::MD4
+         - QCA::MD5
+         - QCA::RIPEMD160
+         - QCA::SHA256
+         - QCA::SHA384
+         - QCA::SHA512
+     - Ciphers (QCA::Cipher)
+         - BlowFish  (QCA::BlowFish)
+         - Triple %DES (QCA::TripleDES)
+         - %DES (QCA::DES)
+         - AES (QCA::AES128, QCA::AES192, QCA::AES256)
+     - Keyed Hash Message Authentication Code (QCA::HMAC), using
+         - SHA1
+         - MD5
+         - RIPEMD160
+  
+   Functionality is supplied via plugins.  This is useful for avoiding
+   dependence on a particular crypto library and makes upgrading easier,
+   as there is no need to recompile your application when adding or
+   upgrading a crypto plugin.  Also, by pushing crypto functionality into
+   plugins, your application is free of legal issues, such as export
+   regulation.
+ 
+   And of course, you get a very simple crypto API for Qt, where you can
+   do things like:
+   \code
+   QString hash = QCA::SHA1().hashToString(blockOfData);
+   \endcode
+
+   \section using Using QCA
+
+   The application simply includes %qca.h and links to libqca,
+   which provides the 'wrapper API' and plugin loader.  Crypto
+   functionality is determined during runtime, and plugins are
+   loaded from the 'crypto' subfolder of the %Qt library paths. There
+   are <a href="examples.html">additional examples available</a>.
+
+   \section availability Availability
+
+   \subsection qca2code Current development
+
+   The latest version of the code is available from the KDE CVS
+   server (there is no formal release of the current version at this time). See
+   <a href="http://developer.kde.org/source/anoncvs.html">
+   http://developer.kde.org/source/anoncvs.html
+   </a> for general instructions. You do <i>not</i> need kdelibs or
+   arts modules for %QCA - just pull down kdesupport/qca. The plugins
+   are in the same tree. Naturally you will need %Qt properly set up
+   and configured in order to build and use %QCA.
+
+   The CVS code can also be browsed
+   <a href="http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdesupport/qca/">
+   via the web</a>
+
+   \subsection qca1code Previous versions
+   
+   A previous version of %QCA (sometimes referred to as QCA1) is still available.
+   You will need to get the main library 
+   (<a href="src/qca1/qca-1.0.tar.bz2">qca-1.0.tar.bz2</a>) and one or
+   more providers
+   (<a href="src/qca1/qca-tls-1.0.tar.bz2">qca-tls-1.0.tar.bz2</a> for
+   the OpenSSL based provider, or
+   <a href="src/qca1/qca-sasl-1.0.tar.bz2">qca-sasl-1.0.tar.bz2</a> for
+   the SASL based provider). Note that development of QCA1 has basically
+   stopped.
+
+ */
+
+#endif
diff --git a/include/QtCrypto/qca_basic.h b/include/QtCrypto/qca_basic.h
new file mode 100644
index 00000000..ae1ae095
--- /dev/null
+++ b/include/QtCrypto/qca_basic.h
@@ -0,0 +1,1208 @@
+/*
+ * qca_basic.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_BASIC_H
+#define QCA_BASIC_H
+
+#include "qca_core.h"
+
+namespace QCA
+{
+	/**
+	 * Source of random numbers
+	 *
+	 * QCA provides a built in source of random numbers, which
+	 * can be accessed through this class. You can also use
+	 * an alternative random number source, by implementing
+	 * another provider.
+	 *
+	 * You can select the "quality" of the random numbers. For 
+	 * best results, you should use Nonce or PublicValue for values
+	 * that are likely to become public, and SessionKey or LongTermKey
+	 * for those values that are more critical. All that said, please
+	 * note that this is only a hint to the provider - it may make
+	 * no difference at all.
+	 *
+	 * The normal use of this class is expected to be through the
+	 * static members - randomChar(), randomInt() and randomArray().
+	 */
+	class QCA_EXPORT Random : public Algorithm
+	{
+	public:
+		/**
+		 * How much entropy to use for the random numbers that
+		 * are required.
+		 */
+		enum Quality { Nonce, PublicValue, SessionKey, LongTermKey };
+
+		/**
+		 * Standard Constructor
+		 *
+		 * \param provider the provider library for the random
+		 *                 number generation
+		 */ 
+		Random(const QString &provider = QString() );
+
+		/**
+		 * Provide a random byte.
+		 *
+		 * This method isn't normally required - you should use
+		 * the static randomChar() method instead.
+		 * 
+		 * \param q the quality of the random byte that is required
+		 *
+		 * \sa randomChar
+		 */
+		uchar nextByte(Quality q = SessionKey);
+
+		/**
+		 * Provide a specified number of random bytes
+		 *
+		 * This method isn't normally required - you should use
+		 * the static randomArray() method instead.
+		 *
+		 * \param size the number of bytes to provide
+		 * \param q the quality of the random bytes that are required
+		 *
+		 * \sa randomArray
+		 */
+		QSecureArray nextBytes(int size, Quality q = SessionKey);
+
+		/**
+		 * Provide a random character (byte)
+		 *
+		 * This is the normal way of obtaining a single random char
+		 * (ie. 8 bit byte), of the default quality, as shown below:
+		 * \code
+		 * myRandomChar = QCA::Random::randomChar();
+		 * \endcode
+		 * 
+		 * \param q the quality of the random character that is required
+		 *
+		 * If you need a number of bytes, perhaps randomArray() may be of use
+		 */
+		static uchar randomChar(Quality q = SessionKey);
+
+		/**
+		 * Provide a random integer
+		 *
+		 * This is the normal way of obtaining a single random integer,
+		 * as shown below:
+		 * \code
+		 * // default quality
+		 * myRandomInt = QCA::Random::randomInt();
+		 * // cheap integer
+		 * myCheapInt = QCA::Random::randomInt( QCA::Random::Nonce );
+		 * \endcode
+		 *
+		 * \param q the quality of the random integer that is required
+		 */
+		static uint randomInt(Quality q = SessionKey);
+
+		/**
+		 * Provide a specified number of random bytes
+		 * 
+		 * \code
+		 * // build a 30 byte secure array.
+		 * QSecureArray arry = QCA::Random::randomArray(30);
+		 * // take 20 bytes, as high a quality as we can get
+		 * QSecureArray newKey = QCA::Random::randomArray(20, QCA::Random::LongTermKey);
+		 * \endcode
+		 *
+		 * \param size the number of bytes to provide
+		 * \param q the quality of the random bytes that are required
+		 */
+		static QSecureArray randomArray(int size, Quality q = SessionKey);
+	};
+
+	/**
+	 * General superclass for hashing algorithms.
+	 *
+	 * %Hash is a superclass for the various hashing algorithms
+	 * within %QCA. You should not need to use it directly unless you are
+	 * adding another hashing capability to %QCA - you should be
+	 * using a sub-class. SHA1 or RIPEMD160 are recommended for
+	 * new applications, although MD2, MD4, MD5 or SHA0 may be
+	 * applicable (for interoperability reasons) for some
+	 * applications. 
+	 *
+	 * To perform a hash, you create an object (of one of the
+	 * sub-classes of %Hash), call update() with the data that
+	 * needs to be hashed, and then call final(), which returns
+	 * a QByteArray of the hash result. An example (using the SHA1
+	 * hash, with 1000 updates of a 1000 byte string) is shown below:
+	 * \code
+	 *        if(!QCA::isSupported("sha1"))
+	 *                printf("SHA1 not supported!\n");
+	 *        else {
+	 *                QByteArray fillerString;
+	 *                fillerString.fill('a', 1000);
+	 *
+	 *                QCA::SHA1 shaHash;
+	 *                for (int i=0; i<1000; i++)
+	 *                        shaHash.update(fillerString);
+	 *                QByteArray hashResult = shaHash.final();
+	 *                if ( "34aa973cd4c4daa4f61eeb2bdbad27316534016f" == QCA::arrayToHex(hashResult) ) {
+	 *                        printf("big SHA1 is OK\n");
+	 *                } else {
+	 *                        printf("big SHA1 failed\n");
+	 *                }
+	 *        }
+	 * \endcode
+	 *
+	 * If you only have a simple hash requirement - a single
+	 * string that is fully available in memory at one time - 
+	 * then you may be better off with one of the convenience
+	 * methods. So, for example, instead of creating a QCA::SHA1
+	 * or QCA::MD5 object, then doing a single update() and the final()
+	 * call; you simply call QCA::SHA1().hash() or
+	 * QCA::MD5().hash() with the data that you would otherwise
+	 * have provided to the update() call.
+	 */
+	class QCA_EXPORT Hash : public Algorithm, public BufferedComputation
+	{
+	public:
+		/**
+		 * Reset a hash, dumping all previous parts of the
+		 * message.
+		 *
+		 * This method clears (or resets) the hash algorithm,
+		 * effectively undoing any previous update()
+		 * calls. You should use this call if you are re-using
+		 * a Hash sub-class object to calculate additional
+		 * hashes.
+		 */
+		virtual void clear();
+
+		/**
+		 * Update a hash, adding more of the message contents
+		 * to the digest. The whole message needs to be added
+		 * using this method before you call final(). 
+		 *
+		 * If you find yourself only calling update() once,
+		 * you may be better off using a convenience method
+		 * such as hash() or hashToString() instead.
+		 *
+ 		 * \param a the byte array to add to the hash 
+		 */
+		virtual void update(const QSecureArray &a);
+
+		/**
+		 * \overload
+		 *
+		 * \param a the QByteArray to add to the hash 
+		 */
+		virtual void update(const QByteArray &a);
+
+		/**
+		 * \overload
+		 *
+		 * This method is provided to assist with code that
+		 * already exists, and is being ported to %QCA. You are
+		 * better off passing a QSecureArray (as shown above)
+		 * if you are writing new code.
+		 *
+		 * \param data pointer to a char array
+		 * \param len the length of the array. If not specified
+		 * (or specified as a negative number), the length will be
+		 * determined with strlen(), which may not be what you want
+		 * if the array contains a null (0x00) character.
+		 */
+		virtual void update(const char *data, int len = -1);
+
+		/**
+		 * \overload
+		 *
+		 * This allows you to read from a file or other
+		 * I/O device. Note that the device must be already
+		 * open for reading
+		 *
+		 * \param file an I/O device
+		 *
+		 * If you are trying to calculate the hash of
+		 * a whole file (and it isn't already open), you
+		 * might want to use code like this:
+		 * \code
+		 * QFile f( "file.dat" );
+		 * if ( f1.open( IO_ReadOnly ) ) {
+		 *     QCA::SHA1 hashObj;
+		 *     hashObj.update( f1 );
+		 *     QString output = hashObj.final() ) ),
+		 * }
+		 * \endcode
+		 */
+		virtual void update(QIODevice &file);
+
+		/**
+		 * Finalises input and returns the hash result
+		 *
+		 * After calling update() with the required data, the
+		 * hash results are finalised and produced.
+		 *
+		 * Note that it is not possible to add further data (with
+		 * update()) after calling final(), because of the way
+		 * the hashing works - null bytes are inserted to pad
+		 * the results up to a fixed size. If you want to
+		 * reuse the Hash object, you should call clear() and
+		 * start to update() again.
+		 */
+		virtual QSecureArray final();
+
+		/**
+		 * %Hash a byte array, returning it as another
+		 * byte array.
+		 * 
+		 * This is a convenience method that returns the
+		 * hash of a QSecureArray.
+		 * 
+		 * \code
+		 * QSecureArray sampleArray(3);
+		 * sampleArray.fill('a');
+		 * QSecureArray outputArray = QCA::MD2::hash(sampleArray);
+		 * \endcode
+		 * 
+		 * \param array the QByteArray to hash
+		 *
+		 * If you need more flexibility (e.g. you are constructing
+		 * a large byte array object just to pass it to hash(), then
+		 * consider creating an Hash sub-class object, and calling
+		 * update() and final().
+		 */
+		QSecureArray hash(const QSecureArray &array);
+
+		/**
+		 * \overload
+		 *
+		 * \param cs the QCString to hash
+		 */
+		QSecureArray hash(const QCString &cs);
+
+		/**
+		 * %Hash a byte array, returning it as a printable
+		 * string
+		 * 
+		 * This is a convenience method that returns the
+		 * hash of a QSeecureArray as a hexadecimal
+		 * representation encoded in a QString.
+		 * 
+		 * \param array the QByteArray to hash
+		 *
+		 * If you need more flexibility, you can create a Hash
+		 * sub-class object, call Hash::update() as
+		 * required, then call Hash::final(), before using
+		 * the static arrayToHex() method.
+		 */
+		QString hashToString(const QSecureArray &array);
+
+		/**
+		 * \overload
+		 *
+		 * \param cs the QCString to hash		 
+		 */
+		QString hashToString(const QCString &cs);
+
+	protected:
+		/**
+		 *  Constructor to override in sub-classes.
+		 *
+		 * \param type label for the type of hash to be
+		 * implemented (eg "sha1" or "md2")
+		 * \param provider the name of the provider plugin
+		 * for the subclass (eg "qca-openssl")
+		 */
+		Hash(const QString &type, const QString &provider);
+	};
+
+        /** \page padding Padding
+
+	For those Cipher sub-classes that are block based, there are modes
+	that require a full block on encryption and decryption - %Cipher Block
+	Chaining mode and Electronic Code Book modes are good examples. 
+	
+	Since real world messages are not always a convenient multiple of a
+	block size, we have to adding <i>padding</i>. There are a number of
+	padding modes that %QCA supports, including not doing any padding
+	at all.
+	
+	If you are not going to use padding, then you can pass 
+	QCA::Cipher::NoPadding as the pad argument to the Cipher sub-class, however
+	it is then your responsibility to pass in appropriate data for
+	the mode that you are using.
+
+	The most common padding scheme is known as PKCS#7 (also PKCS#1), and
+	it specifies that the pad bytes are all equal to the length of the 
+	padding ( for example, if you need three pad bytes to complete the block, then
+	the padding is 0x03 0x03 0x03 ).
+
+	On encryption, for algorithm / mode combinations that require
+	padding, you will get a block of ciphertext when the input plain text block
+	is complete. When you call final(), you will get out the ciphertext that
+	corresponds to the last bit of plain text, plus any padding. If you had
+	provided plaintext that matched up with a block size, then the cipher
+	text block is generated from pure padding - you always get at least some
+	padding, to ensure that the padding can be safely removed on decryption.
+	
+	On decryption, for algorithm / mode combinations that use padding,
+	you will get back a block of plaintext when the input ciphertext block
+	is complete. When you call final(), you will a block that has been stripped
+	of ciphertext.
+	*/
+
+	/**
+	 * General superclass for cipher (encryption / decryption) algorithms.
+	 *
+	 * %Cipher is a superclass for the various algorithms that perform
+	 * low level encryption and decryption within %QCA. You should
+	 * not need to use it directly unless you are
+	 * adding another capability to %QCA - you should be
+	 * using a sub-class. AES is recommended for new applications.
+	 */
+	class QCA_EXPORT Cipher : public Algorithm, public Filter
+	{
+	public:
+		/**
+		 * Mode settings for cipher algorithms
+		 */
+		enum Mode
+		{
+			CBC, ///< operate in %Cipher Block Chaining mode
+			CFB, ///< operate in %Cipher FeedBack mode
+			ECB  ///< operate in Electronic Code Book mode
+		};
+
+		/**
+		 * Padding variations for cipher algorithms
+		 */
+		enum Padding
+		{
+			NoPadding, ///< Do no padding
+			PKCS7     ///< Pad using the scheme in PKCS#7
+		};
+
+		/** 
+		 * Standard copy constructor
+		 */
+		Cipher(const Cipher &from);
+		~Cipher();
+
+		Cipher & operator=(const Cipher &from);
+
+		/**
+		 * Return acceptable key lengths
+		 */
+		KeyLength keyLength() const;
+
+		/**
+		 * Test if a key length is valid for the cipher algorithm
+		 *
+		 * \param n the key length in bytes
+		 * \return true if the key would be valid for the current algorithm
+		 */
+		bool validKeyLength(int n) const;
+
+		/**
+		 * return the block size for the cipher object
+		 */
+		uint blockSize() const;
+
+		/**
+		 * reset the cipher object, to allow re-use
+		 */
+		virtual void clear();
+
+		/** 
+		 * pass in a byte array of data, which will be encrypted or decrypted
+		 * (according to the Direction that was set in the constructor or in
+		 * setup() ) and returned.
+		 *
+		 * \param a the array of data to encrypt / decrypt
+		 */
+		virtual QSecureArray update(const QSecureArray &a);
+
+		/**
+		 * complete the block of data, padding as required, and returning
+		 * the completed block
+		 */
+		virtual QSecureArray final();
+
+		virtual bool ok() const;
+
+		// note: padding only applies to CBC and ECB.  CFB ciphertext is
+		//   always the length of the plaintext.
+		void setup(Mode m, Direction dir, const SymmetricKey &key, const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7);
+
+	protected:
+		Cipher(const QString &type, Mode m, Direction dir, const SymmetricKey &key, const InitializationVector &iv, Padding pad, const QString &provider);
+	private:
+		class Private;
+		Private *d;
+	};
+
+	/**
+	 * General superclass for message authentication code (MAC) algorithms.
+	 *
+	 * %MessageAuthenticationCode is a superclass for the various 
+	 * message authentication code algorithms within %QCA. You should
+	 * not need to use it directly unless you are
+	 * adding another message authentication code capability to %QCA - you should be
+	 * using a sub-class. HMAC using SHA1 is recommended for new applications.
+	 */
+	class QCA_EXPORT MessageAuthenticationCode : public Algorithm, public BufferedComputation
+	{
+	public:
+		/**
+		 * Standard copy constructor
+		 */
+		MessageAuthenticationCode(const MessageAuthenticationCode &from);
+
+		~MessageAuthenticationCode();
+
+		/**
+		 * Assignment operator.
+		 *
+		 * Copies the state (including key) from one MessageAuthenticationCode
+		 * to another
+		 */
+		MessageAuthenticationCode & operator=(const MessageAuthenticationCode &from);
+
+		/**
+		 * Return acceptable key lengths
+		 */
+		KeyLength keyLength() const;
+
+		/**
+		 * Test if a key length is valid for the MAC algorithm
+		 *
+		 * \param n the key length in bytes
+		 * \return true if the key would be valid for the current algorithm
+		 */
+		bool validKeyLength(int n) const;
+		
+		/**
+		 * Reset a MessageAuthenticationCode, dumping all
+		 * previous parts of the message.
+		 *
+		 * This method clears (or resets) the algorithm,
+		 * effectively undoing any previous update()
+		 * calls. You should use this call if you are re-using
+		 * a %MessageAuthenticationCode sub-class object
+		 * to calculate additional MACs. Note that if the key
+		 * doesn't need to be changed, you don't need to call
+		 * setup() again, since the key can just be reused.
+		 */
+		virtual void clear();
+
+		/**
+		 * Update the MAC, adding more of the message contents
+		 * to the digest. The whole message needs to be added
+		 * using this method before you call final(). 
+		 *
+		 * \param array the message contents
+		 */
+		virtual void update(const QSecureArray &array);
+
+		/**
+		 * Finalises input and returns the MAC result
+		 *
+		 * After calling update() with the required data, the
+		 * hash results are finalised and produced.
+		 *
+		 * Note that it is not possible to add further data (with
+		 * update()) after calling final(). If you want to
+		 * reuse the %MessageAuthenticationCode object, you
+		 * should call clear() and start to update() again.
+		 */
+		virtual QSecureArray final();
+
+		/**
+		 * Initialise the MAC algorithm.
+		 *
+		 * \param key the key to use for the algorithm
+		 */
+		void setup(const SymmetricKey &key);
+
+		/**
+		 * Construct the name of the algorithm
+		 *
+		 * You can use this to build a standard name string.
+		 * You probably only need this method if you are 
+		 * creating a new subclass.
+		 */
+		static QString withAlgorithm(const QString &macType, const QString &algType);
+
+	protected:
+		/**
+		 * Special constructor for subclass initialisation
+		 *
+		 * To create HMAC with a default algorithm of "sha1", you would use something like:
+		 * \code
+		 * HMAC(const QString &hash = "sha1", const SymmetricKey &key = SymmetricKey(), const QString &provider = QString() )
+		 * : MessageAuthenticationCode(withAlgorithm("hmac", hash), key, provider)
+		 * {
+		 * }
+		 * \endcode
+		 *
+		 * \note The HMAC subclass is already provided in QCA - you don't need to create
+		 * your own.
+		 */
+		MessageAuthenticationCode(const QString &type, const SymmetricKey &key, const QString &provider);
+
+	private:
+		class Private;
+		Private *d;
+	};
+
+
+	/**
+	 * SHA-0 cryptographic message digest hash algorithm.
+	 *
+	 * %SHA0 is a 160 bit hashing function, no longer recommended
+	 * for new applications because of known (partial) attacks
+	 * against it.
+	 *
+	 * You can use this class in two basic ways - standard member
+	 * methods, and convenience methods. Both are shown in
+	 * the example below.
+	 *
+	 * \code
+	 *        if(!QCA::isSupported("sha0"))
+	 *                printf("SHA0 not supported!\n");
+	 *        else {
+	 *                QCString actualResult;
+	 *                actualResult = QCA::SHA0().hashToString(message);
+	 *
+	 *                // normal methods - update() and final()
+	 *                QByteArray fillerString;
+	 *                fillerString.fill('a', 1000);
+	 *                QCA::SHA0 shaHash;
+	 *                for (int i=0; i<1000; i++)
+	 *                        shaHash.update(fillerString);
+	 *                QByteArray hashResult = shaHash.final();
+	 *        }
+	 * \endcode
+	 *
+	 */
+	class QCA_EXPORT SHA0 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a SHA-0 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using QCA::SHA0().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the SHA0 implementation
+		 * from qca-openssl, you would use SHA0("qca-openssl")
+		 */
+		SHA0(const QString &provider = QString() ) : Hash("sha0", provider) {}
+	};
+
+	/**
+	 * SHA-1 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message (up to \f$2^{64}\f$ bits in length) and outputs a
+	 * condensed 160 bit (20 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is considered secure in that it is considered
+	 * computationally infeasible to find the message that
+	 * produced the message digest.
+	 *
+	 * You can use this class in two basic ways - standard member
+	 * methods, and convenience methods. Both are shown in
+	 * the example below.
+	 *
+	 * \code
+	 *        if(!QCA::isSupported("sha1"))
+	 *                printf("SHA1 not supported!\n");
+	 *        else {
+	 *                QCString actualResult;
+	 *                actualResult = QCA::SHA1().hashToString(message);
+	 *
+	 *                // normal methods - update() and final()
+	 *                QByteArray fillerString;
+	 *                fillerString.fill('a', 1000);
+	 *                QCA::SHA1 shaHash;
+	 *                for (int i=0; i<1000; i++)
+	 *                        shaHash.update(fillerString);
+	 *                QByteArray hashResult = shaHash.final();
+	 *        }
+	 * \endcode
+	 *
+	 * For more information, see Federal Information Processing
+	 * Standard Publication 180-2 "Specifications for the Secure
+	 * %Hash Standard", available from http://csrc.nist.gov/publications/
+	 */
+	class QCA_EXPORT SHA1 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a SHA-1 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using QCA::SHA1().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the SHA1 implementation
+		 * from qca-openssl, you would use SHA1("qca-openssl")
+		 */
+		SHA1(const QString &provider = QString() ) : Hash("sha1", provider) {}
+	};
+
+	/**
+	 * SHA-256 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message (up to \f$2^{64}\f$ bits in length) and outputs a
+	 * condensed 256 bit (32 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is considered secure in that it is considered
+	 * computationally infeasible to find the message that
+	 * produced the message digest.
+	 *
+	 * For more information, see Federal Information Processing
+	 * Standard Publication 180-2 "Specifications for the Secure
+	 * %Hash Standard", available from http://csrc.nist.gov/publications/
+	 */
+	class QCA_EXPORT SHA256 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a SHA256 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using
+		 * QCA::SHA256().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the SHA256 implementation
+		 * from qca-gcrypt, you would use SHA256("qca-gcrypt")
+		 */
+		SHA256(const QString &provider = QString() ) : Hash("sha256", provider) {}
+	};
+
+	/**
+	 * SHA-384 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message (up to \f$2^{128}\f$ bits in length) and outputs a
+	 * condensed 384 bit (48 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is considered secure in that it is considered
+	 * computationally infeasible to find the message that
+	 * produced the message digest.
+	 *
+	 * For more information, see Federal Information Processing
+	 * Standard Publication 180-2 "Specifications for the Secure
+	 * %Hash Standard", available from http://csrc.nist.gov/publications/
+	 */
+	class QCA_EXPORT SHA384 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a SHA384 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using
+		 * QCA::SHA384().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the SHA384 implementation
+		 * from qca-gcrypt, you would use SHA384("qca-gcrypt")
+		 */
+		SHA384(const QString &provider = QString() ) : Hash("sha384", provider) {}
+	};
+
+	/**
+	 * SHA-512 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message (up to \f$2^{128}\f$ bits in length) and outputs a
+	 * condensed 512 bit (64 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is considered secure in that it is considered
+	 * computationally infeasible to find the message that
+	 * produced the message digest.
+	 *
+	 * For more information, see Federal Information Processing
+	 * Standard Publication 180-2 "Specifications for the Secure
+	 * %Hash Standard", available from http://csrc.nist.gov/publications/
+	 */
+	class QCA_EXPORT SHA512 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a SHA512 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using
+		 * QCA::SHA512().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the SHA512 implementation
+		 * from qca-gcrypt, you would use SHA512("qca-gcrypt")
+		 */
+		SHA512(const QString &provider = QString() ) : Hash("sha512", provider) {}
+	};
+
+	/**
+	 * %MD2 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message and outputs a
+	 * condensed 128 bit (16 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is considered slightly more secure than MD5,
+	 * but is more expensive to compute. Unless backward
+	 * compatibility or interoperability are considerations, you
+	 * are better off using the SHA1 or RIPEMD160 hashing algorithms.
+	 *
+	 * For more information, see B. Kalinski RFC1319 "The %MD2
+	 * Message-Digest Algorithm".
+	 */
+	class QCA_EXPORT MD2 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating an MD-2 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using QCA::MD2().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the MD2 implementation
+		 * from qca-openssl, you would use MD2("qca-openssl")
+		 */
+		MD2(const QString &provider = QString() ) : Hash("md2", provider) {}
+	};
+
+	/**
+	 * %MD4 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message and outputs a
+	 * condensed 128 bit (16 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is not considered to be secure, based on
+	 * known attacks. It should only be used for
+	 * applications where collision attacks are not a
+	 * consideration (for example, as used in the rsync algorithm
+	 * for fingerprinting blocks of data). If a secure hash is
+	 * required, you are better off using the SHA1 or RIPEMD160
+	 * hashing algorithms. MD2 and MD5 are both stronger 128 bit
+	 * hashes.
+	 *
+	 * For more information, see R. Rivest RFC1320 "The %MD4
+	 * Message-Digest Algorithm".
+	 */
+	class QCA_EXPORT MD4 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating an MD-4 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using QCA::MD4().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the MD4 implementation
+		 * from qca-openssl, you would use MD4("qca-openssl")
+		 */
+		MD4(const QString &provider = QString() ) : Hash("md4", provider) {}
+	};
+
+	/**
+	 * %MD5 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message and outputs a
+	 * condensed 128 bit (16 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is not considered to be secure, based on
+	 * known attacks. It should only be used for
+	 * applications where collision attacks are not a
+	 * consideration. If a secure hash is
+	 * required, you are better off using the SHA1 or RIPEMD160
+	 * hashing algorithms.
+	 *
+	 * For more information, see R. Rivest RFC1321 "The %MD5
+	 * Message-Digest Algorithm".
+	 */
+	class QCA_EXPORT MD5 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating an MD-5 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using QCA::MD5().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the MD5 implementation
+		 * from qca-openssl, you would use MD5("qca-openssl")
+		 */
+		MD5(const QString &provider = QString() ) : Hash("md5", provider) {}
+	};
+
+	/**
+	 * %RIPEMD160 cryptographic message digest hash algorithm.
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message (up to \f$2^{64}\f$ bits in length) and outputs a
+	 * condensed 160 bit (20 byte) representation of that data
+	 * stream, known as the message digest.
+	 *
+	 * This algorithm is considered secure in that it is considered
+	 * computationally infeasible to find the message that
+	 * produced the message digest.
+	 *
+	 * You can use this class in two basic ways - standard member
+	 * methods, and convenience methods. Both are shown in
+	 * the example below.
+	 *
+	 * \code
+	 *        if(!QCA::isSupported("ripemd160")
+	 *                printf("RIPEMD-160 not supported!\n");
+	 *        else {
+	 *                QCString actualResult;
+	 *                actualResult = QCA::RIPEMD160().hashToString(message);
+	 *
+	 *                // normal methods - update() and final()
+	 *                QByteArray fillerString;
+	 *                fillerString.fill('a', 1000);
+	 *                QCA::RIPEMD160 ripemdHash;
+	 *                for (int i=0; i<1000; i++)
+	 *                        ripemdHash.update(fillerString);
+	 *                QByteArray hashResult = ripemdHash.final();
+	 *        }
+	 * \endcode
+	 *
+	 */
+	class QCA_EXPORT RIPEMD160 : public Hash
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a RIPEMD160 hash,
+		 * although if you have the whole message in memory at
+		 * one time, you may be better off using
+		 * QCA::RIPEMD160().hash()
+		 *
+		 * \param provider specify a particular provider 
+		 * to use. For example if you wanted the RIPEMD160
+		 * implementation from qca-openssl, you would use 
+		 * RIPEMD160("qca-openssl")
+		 */
+		RIPEMD160(const QString &provider = QString() ) : Hash("ripemd160", provider) {}
+	};
+
+	/**
+	 * Bruce Schneier's Blowfish %Cipher
+	 *
+	 */
+	class QCA_EXPORT BlowFish : public Cipher
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a %BlowFish encryption or decryption object.
+		 *
+		 * \param m the Mode to operate in
+		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
+		 * \param key the key to use. 
+		 * \param iv the initialisation vector to use. Ignored for ECB mode.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
+		 * \param provider the provider to use (eg "qca-gcrypt" )
+		 *
+		 */
+		BlowFish(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
+		:Cipher("blowfish", m, dir, key, iv, pad, provider) {}
+	};
+
+	/**
+	 * Triple %DES %Cipher
+	 *
+	 */
+	class QCA_EXPORT TripleDES : public Cipher
+	{
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a triple %DES encryption or decryption object.
+		 *
+		 * \param m the Mode to operate in
+		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
+		 * \param key the key to use. Note that triple %DES requires a 24 byte (192 bit) key,
+		 * even though the effective key length is 168 bits.
+		 * \param iv the initialisation vector to use. Ignored for ECB mode.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
+		 * \param provider the provider to use (eg "qca-gcrypt" )
+		 *
+		 */
+	public:
+		TripleDES(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
+		:Cipher("tripledes", m, dir, key, iv, pad, provider) {}
+	};
+
+	/**
+	 * %DES %Cipher
+	 *
+	 */
+	class QCA_EXPORT DES : public Cipher
+	{
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a %DES encryption or decryption object.
+		 *
+		 * \param m the Mode to operate in
+		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
+		 * \param key the key to use. Note that %DES requires a 8 byte (64 bit) key,
+		 * even though the effective key length is 56 bits.
+		 * \param iv the initialisation vector to use. Ignored for ECB mode.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
+		 * \param provider the provider to use (eg "qca-gcrypt" )
+		 *
+		 */
+	public:
+		DES(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
+		:Cipher("des", m, dir, key, iv, pad, provider) {}
+	};
+
+	/**
+	 * Advanced Encryption Standard %Cipher - 128 bits
+	 *
+	 */
+	class QCA_EXPORT AES128 : public Cipher
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a 128 bit 
+		 * AES encryption or decryption object.
+		 *
+		 * \param m the Mode to operate in
+		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
+		 * \param key the key to use. Note that AES128 requires a 16 byte (128 bit) key.
+		 * \param iv the initialisation vector to use. Ignored for ECB mode.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
+		 * \param provider the provider to use (eg "qca-gcrypt" )
+		 *
+		 */
+		AES128(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
+		:Cipher("aes128", m, dir, key, iv, pad, provider) {}
+	};
+
+	/**
+	 * Advanced Encryption Standard %Cipher - 192 bits
+	 *
+	 */
+	class QCA_EXPORT AES192 : public Cipher
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a 192 bit 
+		 * AES encryption or decryption object.
+		 *
+		 * \param m the Mode to operate in
+		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
+		 * \param key the key to use. Note that AES192 requires a 24 byte (192 bit) key.
+		 * \param iv the initialisation vector to use. Ignored for ECB mode.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
+		 * \param provider the provider to use (eg "qca-gcrypt" )
+		 *
+		 */
+		AES192(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
+		:Cipher("aes192", m, dir, key, iv, pad, provider) {}
+	};
+
+	/**
+	 * Advanced Encryption Standard %Cipher - 256 bits
+	 *
+	 */
+	class QCA_EXPORT AES256 : public Cipher
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * This is the normal way of creating a 256 bit 
+		 * AES encryption or decryption object.
+		 *
+		 * \param m the Mode to operate in
+		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
+		 * \param key the key to use. Note that AES256 requires a 32 byte (256 bit) key.
+		 * \param iv the initialisation vector to use. Ignored for ECB mode.
+		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
+		 *        Mode does not require padding
+		 * \param provider the provider to use (eg "qca-gcrypt" )
+		 *
+		 */
+		AES256(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
+		:Cipher("aes256", m, dir, key, iv, pad, provider) {}
+	};
+
+
+	/**
+	 * Keyed %Hash message authentication codes
+	 *
+	 * This algorithm takes an arbitrary data stream, known as the
+	 * message and outputs an authentication code for that message.
+	 * The authentication code is generated using a secret key in
+	 * such a way that the authentication code shows that the 
+	 * message has not be altered.
+	 *
+	 * As an example, to create a MAC using HMAC with SHA1, you
+	 * could do the following:
+	 * \code
+	 * if( QCA::isSupported( "hmac(sha1)" ) ) {
+	 *      QCA::HMAC hmacObj; // don't need to specify, "sha1" is default
+	 *	hmacObj.setup( key ); // key is a QCA::SymmetricKey, set elsewhere
+	 *                            // could also be done in constructor
+	 *    	hmacObj.update( dataArray ); // dataArray is a QSecureArray, set elsewhere
+	 *	output = hmacObj.final();
+	 * }
+	 * \endcode
+	 *
+	 * Note that if your application is potentially susceptable to "replay attacks"
+	 * where the message is sent more than once, you should include a counter in
+	 * the message that is covered by the MAC, and check that the counter is always
+	 * incremented every time you recieve a message and MAC.
+	 *
+	 * For more information, see H. Krawczyk et al. RFC2104 
+	 * "HMAC: Keyed-Hashing for Message Authentication"
+	 */
+	class QCA_EXPORT HMAC : public MessageAuthenticationCode
+	{
+	public:
+		/**
+		 * %HMAC constructor
+		 *
+		 * To create a simple HMAC object
+		 * \param hash the type of the hash (eg "sha1", "md5" or "ripemd160" )
+		 * \param key the key to use for the HMAC algorithm.
+		 * \param provider the name of the provider to use (eg "qca-openssl")
+		 *
+		 * To construct a keyed-hash message authentication code object, you
+		 * can do one of the following variations.
+		 * \code
+		 * QCA::HMAC sha1HMAC; // defaults to SHA1
+		 * QCA::HMAC sha1HMAC( "sha1" ); // explicitly SHA1, but same as above
+		 * QCA::HMAC md5HMAC( "md5" );  // MD5 algorithm
+		 * QCA::HMAC sha1HMAC( "sha1", key ); // key is a QCA::SymmetricKey
+		 * // next line uses RIPEMD160, empty key, implementation from qca-openssl provider
+		 * QCA::HMAC ripemd160HMAC( "ripemd160", QCA::SymmetricKey(), "qca-openssl" );
+		 * \endcode
+		 */
+		HMAC(const QString &hash = "sha1", const SymmetricKey &key = SymmetricKey(), const QString &provider = QString() ) : MessageAuthenticationCode(withAlgorithm("hmac", hash), key, provider) {}
+	};
+
+
+	/**
+	 * General superclass for key derivation algorithms.
+	 *
+	 * %KeyDerivationFunction is a superclass for the various 
+	 * key derivation function algorithms within %QCA. You should
+	 * not need to use it directly unless you are
+	 * adding another key derivation capability to %QCA - you should be
+	 * using a sub-class. PBKDF2 using SHA1 is recommended for new applications.
+	 */
+	class QCA_EXPORT KeyDerivationFunction : public Algorithm
+	{
+	public:
+		/**
+		 * Standard copy constructor
+		 */
+		KeyDerivationFunction(const KeyDerivationFunction &from);
+
+		~KeyDerivationFunction();
+
+		/**
+		 * Generate the key from a specified secret and salt value.
+		 * 
+		 * \note key length is ignored for some functions
+		 *
+		 * \param secret the secret (password or passphrase)
+		 * \param salt the salt to use
+		 * \param keyLength the length of key to return
+		 * \param iterationCount the number of iterations to perform
+		 *
+		 * \return the derived key
+		 */
+		SymmetricKey makeKey(const QSecureArray &secret,
+				     const InitializationVector &salt,
+				     unsigned int keyLength,
+				     unsigned int iterationCount);
+
+		/**
+		 * Construct the name of the algorithm
+		 *
+		 * You can use this to build a standard name string.
+		 * You probably only need this method if you are 
+		 * creating a new subclass.
+		 */
+		static QString withAlgorithm(const QString &kdfType, const QString &algType);
+
+	protected:
+		/**
+		 * Special constructor for subclass initialisation
+ 		 */
+		KeyDerivationFunction(const QString &type, const QString &provider);
+
+	private:
+		class Private;
+		Private *d;
+	};
+
+	class QCA_EXPORT PBKDF1 : public KeyDerivationFunction
+	{
+	public:
+	    PBKDF1(const QString &algorithm = "sha1", const QString &provider = QString() ) : KeyDerivationFunction(withAlgorithm("pbkdf1", algorithm), provider) {}
+	};
+}
+
+#endif
diff --git a/include/QtCrypto/qca_cert.h b/include/QtCrypto/qca_cert.h
new file mode 100644
index 00000000..b8e6d4dd
--- /dev/null
+++ b/include/QtCrypto/qca_cert.h
@@ -0,0 +1,107 @@
+/*
+ * qca_cert.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_CERT_H
+#define QCA_CERT_H
+
+#include <qmap.h>
+#include "qca_core.h"
+
+class QDateTime;
+
+namespace QCA
+{
+	class PublicKey;
+
+	class QCA_EXPORT Certificate : public Algorithm
+	{
+	public:
+		typedef QMap<QString, QString> Info;
+
+		Certificate();
+
+		bool isNull() const;
+
+		QDateTime notValidBefore() const;
+		QDateTime notValidAfter() const;
+
+		Info subjectInfo() const;
+		Info issuerInfo() const;
+
+		QString commonName() const;
+		QBigInteger serialNumber() const;
+		PublicKey subjectPublicKey() const;
+		SignAlgo signatureAlgorithm() const;
+		bool isCA() const;
+		bool isSelfSigned() const;
+
+		// import / export
+		QSecureArray toDER() const;
+		QString toPEM() const;
+		static Certificate fromDER(const QSecureArray &a, const QString &provider = QString() );
+		static Certificate fromPEM(const QString &s, const QString &provider = QString() );
+
+		bool matchesHostname(const QString &host) const;
+
+		bool operator==(const Certificate &a) const;
+		bool operator!=(const Certificate &a) const;
+
+	private:
+		friend class Store;
+		friend class TLS;
+	};
+
+	class QCA_EXPORT CRL : public Algorithm
+	{
+	public:
+		CRL();
+
+		bool isNull() const;
+
+		int number() const;
+		QDateTime thisUpdate() const;
+		QDateTime nextUpdate() const;
+
+		// import / export
+		QSecureArray toDER() const;
+		QString toPEM() const;
+		static CRL fromDER(const QSecureArray &a, const QString &provider = QString() );
+		static CRL fromPEM(const QString &s, const QString &provider = QString() );
+
+	private:
+		friend class Store;
+	};
+
+	class QCA_EXPORT Store : public Algorithm
+	{
+	public:
+		Store(const QString &provider = QString() );
+
+		void addCertificate(const Certificate &cert, bool trusted = false);
+		void addCRL(const CRL &crl);
+		CertValidity validate(const Certificate &cert, CertUsage u = Any) const;
+
+	private:
+		friend class TLS;
+	};
+}
+
+#endif
diff --git a/include/QtCrypto/qca_core.h b/include/QtCrypto/qca_core.h
new file mode 100644
index 00000000..2dbfd1dc
--- /dev/null
+++ b/include/QtCrypto/qca_core.h
@@ -0,0 +1,833 @@
+/*
+ * qca_core.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_CORE_H
+#define QCA_CORE_H
+
+#define QCA_VERSION 0x020000
+
+#include <qptrlist.h>
+#include <qstringlist.h>
+#include "qca_export.h"
+#include "qca_tools.h"
+
+// Direct secure memory access.  For interfacing with C libraries if needed.
+QCA_EXPORT void *qca_secure_alloc(int bytes);
+QCA_EXPORT void qca_secure_free(void *p);
+
+/** 
+ * QCA - the Qt Cryptographic Architecture
+ */
+namespace QCA
+{
+	class Provider;
+	class Random;
+	class Store;
+
+	/**
+	 * Convenience representation for the plugin providers
+	 * 
+	 * You can get a list of providers using the providers()
+	 * function
+	 *
+	 * \sa ProviderListIterator
+	 * \sa providers()
+	 */
+	typedef QPtrList<Provider> ProviderList;
+
+	/**
+	 * Convenience representation for iterator for the plugin providers
+	 *
+	 * You would use this something like the following:
+	 * \code
+	 * QCA::ProviderList qcaProviders = QCA::providers();
+	 * QCA::ProviderListIterator it( qcaProviders );
+	 * QCA::Provider *provider;
+	 * while ( 0 != (provider = it.current() ) ) {
+	 *     ++it;
+	 *     cout << provider->name();
+	 * }
+	 * \endcode
+	 *
+	 * \sa ProviderList
+	 * \sa providers()
+	 */
+	typedef QPtrListIterator<Provider> ProviderListIterator;
+
+	/**
+	 * Mode settings for memory allocation
+	 *
+	 * QCA can use secure memory, however most operating systems
+	 * restrict the amount of memory that can be pinned by user
+	 * applications, to prevent a denial-of-service attack. 
+	 *
+	 * QCA supports two approaches to getting memory - the mlock
+	 * method, which generally requires root (administrator) level
+	 * privileges, and the mmap method which is not as secure, but
+	 * which should be able to be used by any process.
+	 * 
+	 * \sa Initializer
+	 */
+	enum MemoryMode
+	{
+		Practical, ///< mlock and drop root if available, else mmap
+		Locking, ///< mlock and drop root
+		LockingKeepPrivileges ///< mlock, retaining root privileges
+	};
+
+	/**
+	 * Direction settings for symmetric algorithms
+	 *
+	 * For some algorithms, it makes sense to have a "direction", such
+	 * as Cipher algorithms which can be used to encrypt or decrypt.
+	 */
+	enum Direction
+	{
+		Encode, ///< Operate in the "forward" direction; for example, encrypting
+		Decode  ///< Operate in the "reverse" direction; for example, decrypting
+	};
+
+	enum DL_Group
+	{
+		DSA_512,
+		DSA_768,
+		DSA_1024,
+		IETF_768,
+		IETF_1024,
+		IETF_1536,
+		IETF_2048,
+		IETF_3072,
+		IETF_4096
+	};
+
+	enum EncAlgo
+	{
+		EME_PKCS1v15,
+		EME_PKCS1_OAEP
+	};
+
+	enum SignAlgo
+	{
+		SignUnknown,
+		EMSA1_SHA1, // usual dsa
+		EMSA3_SHA1,
+		EMSA3_MD5, // usual rsa
+		EMSA3_MD2,
+		EMSA3_RIPEMD160
+	};
+
+	enum CertValidity
+	{
+		Valid,
+		Rejected,
+		Untrusted,
+		SignatureFailed,
+		InvalidCA,
+		InvalidPurpose,
+		SelfSigned,
+		Revoked,
+		PathLengthExceeded,
+		Expired,
+		Unknown
+	};
+
+	enum CertUsage
+	{
+		Any             = 0x00,
+		TLSServer       = 0x01,
+		TLSClient       = 0x02,
+		CodeSigning     = 0x04,
+		EmailProtection = 0x08,
+		TimeStamping    = 0x10,
+		CRLSigning      = 0x20
+	};
+
+	/**
+	 * Specify the lower-bound for acceptable TLS/SASL security layers
+	 */
+	enum SecurityLevel
+	{
+		SL_None,      ///< indicates that no security is ok
+		SL_Integrity, ///< must at least get integrity protection
+		SL_Export,    ///< must be export level bits or more
+		SL_Baseline,  ///< must be 128 bit or more
+		SL_High,      ///< must be more than 128 bit
+		SL_Highest    ///< SL_High or max possible, whichever is greater
+	};
+
+	/**
+	 * Initialise %QCA.
+	 * This call is not normally required, because it is cleaner
+	 * to use an Initializer.
+	 */
+	QCA_EXPORT void init();
+
+	/**
+	 * \overload
+	 *
+	 * \param m the MemoryMode to use
+	 * \param prealloc the amount of memory in kilobytes to allocate
+	 *                 for secure storage
+	 */
+	QCA_EXPORT void init(MemoryMode m, int prealloc);
+
+	/**
+	 * Clean up routine
+	 *
+	 * This routine cleans up %QCA, including memory allocations
+	 * This call is not normally required, because it is cleaner
+	 * to use an Initializer
+	 */
+	QCA_EXPORT void deinit();
+
+	/**
+	 * Test if secure storage memory is available
+	 *
+	 * \return true if secure storage memory is available
+	 */ 
+	QCA_EXPORT bool haveSecureMemory();
+
+	/**
+	 * Test if a capability (algorithm) is available.
+	 *
+	 * Since capabilities are made available at runtime, you
+	 * should always check before using a capability the first
+	 * time, as shown below.
+	 * \code
+	 * QCA::init();
+         * if(!QCA::isSupported("sha1"))
+         *     printf("SHA1 not supported!\n");
+	 * else {
+         *     QString result = QCA::SHA1::hashToString(myString);
+         *     printf("sha1(\"%s\") = [%s]\n", myString.data(), result.latin1());
+	 * }
+	 * \endcode
+	 * 
+	 * \param features the name of the capability to test for
+	 *
+	 * \return true if the capability is available, otherwise false
+	 *
+	 * Note that you can test for a combination of capabilities,
+	 * using a comma delimited list:
+	 * \code
+	 * QCA::isSupported("sha1,md5"):
+	 * \endcode
+	 * which will return true if all of the capabilities listed
+	 * are present.
+	 *
+	 */
+	QCA_EXPORT bool isSupported(const char *features);
+
+	/**
+	 * \overload
+	 *
+	 * \param features a list of features to test for
+	 */
+	QCA_EXPORT bool isSupported(const QStringList &features);
+
+	/**
+	 * Generate a list of all the supported features in plugins,
+	 * and in built in capabilities
+	 *
+	 * \return a list containing the names of the features
+	 *
+	 * The following code writes a list of features to standard out
+	 * \code 
+	 * QStringList capabilities;
+	 * capabilities = QCA::supportedFeatures();
+	 * std::cout << "Supported:" << capabilities.join(",") << std::endl;
+	 * \endcode
+	 *
+	 * \sa isSupported(const char *features)
+	 * \sa isSupported(const QStringList &features)
+	 * \sa defaultFeatures()
+	 */
+	QCA_EXPORT QStringList supportedFeatures();
+
+	/**
+	 * Generate a list of the built in features. This differs from
+	 * supportedFeatures() in that it does not include features provided
+	 * by plugins.
+	 *
+	 * \return a list containing the names of the features
+	 *
+	 * The following code writes a list of features to standard out
+	 * \code 
+	 * QStringList capabilities;
+	 * capabilities = QCA::defaultFeatures();
+	 * std::cout << "Default:" << capabilities.join(",") << std::endl;
+	 * \endcode
+	 *
+	 * \sa isSupported(const char *features)
+	 * \sa isSupported(const QStringList &features)
+	 * \sa supportedFeatures()
+	 */
+	QCA_EXPORT QStringList defaultFeatures();
+
+	/**
+	 * Add a provider to the current list of providers
+	 * 
+	 * This function allows you to add a provider to the 
+	 * current plugin providers at a specified priority. If
+	 * a provider with the name already exists, this call fails.
+	 *
+	 * \param p a pointer to a Provider object, which must be
+	 *        set up.
+	 * \param priority the priority level to set the provider to
+	 *
+	 * \return true if the provider is added, and false if the 
+	 *         provider is not added (failure)
+	 *
+	 * \sa setProviderPriority for a description of the provider priority system
+	 */
+	QCA_EXPORT bool insertProvider(Provider *p, int priority = 0);
+
+	/**
+	 * Change the priority of a specified provider
+	 *
+	 * QCA supports a number of providers, and if a number of providers
+	 * support the same algorithm, it needs to choose between them. You
+	 * can do this at object instantiation time (by specifying the name
+	 * of the provider that should be used). Alternatively, you can provide a
+	 * relative priority level at an application level, using this call.
+	 * 
+	 * Priority is used at object instantiation time. The provider is selected
+	 * according to the following logic:
+	 * - if a particular provider is nominated, and that provider supports
+	 *   the required algorithm, then the nominated provider is used
+	 * - if no provider is nominated, or it doesn't support the required
+	 *   algorithm, then the provider with the lowest priority number will be used,
+	 *   if that provider supports the algorithm.
+	 * - if the provider with the lowest priority number doesn't support 
+	 *   the required algorithm, the provider with the next lowest priority number
+	 *   will be tried,and so on through to the provider with the largest priority number
+	 * - if none of the plugin providers support the required algorithm, then
+	 *   the default (built-in) provider will be tried.
+	 * 
+	 * \param name the name of the provider
+	 * \param priority the new priority of the provider. As a special case, if
+	 *        you pass in -1, then this provider gets the same priority as the
+	 *        the last provider that was added or had its priority set using this
+	 *        call.
+	 *
+	 * \sa providerPriority
+	 */
+	QCA_EXPORT void setProviderPriority(const QString &name, int priority);
+
+	/**
+	 * Return the priority of a specified provider
+	 *
+	 * The name of the provider (eg "qca-openssl") is used to look up the 
+	 * current priority associated with that provider. If the provider
+	 * is not found (or something else went wrong), -1 is returned.
+	 *
+	 * \param name the name of the provider
+	 *
+	 * \return the current priority level
+	 *
+	 * \sa setProviderPriority for a description of the provider priority system
+	 */
+	QCA_EXPORT int providerPriority(const QString &name);
+
+	/**
+	 * Return a list of the current providers
+	 *
+	 * The current plugin providers are provided as a list, which you
+	 * can iterate over using ProviderListIterator.
+	 *
+	 * \sa ProviderList
+	 * \sa ProviderListIterator
+	 */
+	QCA_EXPORT const ProviderList & providers();
+
+	/**
+	 * Unload the current plugins
+	 *
+	 */
+	QCA_EXPORT void unloadAllPlugins();
+
+	/**
+	 * Return the Random provider that is currently set to be the
+	 * global random number generator.
+	 *
+	 * For example, to get the name of the provider that is currently
+	 * providing the Random capability, you could use:
+	 * \code
+	 * QCA::Random rng = QCA::globalRNG();
+         * std::cout << "Provider name: " << rng.provider()->name() << std::endl;
+	 * \endcode
+	 */
+	QCA_EXPORT Random & globalRNG();
+
+	/**
+	 * Change the global random generation provider
+	 *
+	 * The Random capabilities of %QCA are provided as part of the
+	 * built in capabilities, however the generator can be changed
+	 * if required.
+	 */
+	QCA_EXPORT void setGlobalRNG(const QString &provider);
+
+	QCA_EXPORT bool haveSystemStore();
+	QCA_EXPORT Store systemStore(const QString &provider = QString() );
+
+	/**
+	 * Get the application name that will be used by SASL server mode
+	 *
+	 * The application name is used by SASL in server mode, as some systems might
+	 * have different security policies depending on the app.
+	 * The default application name  is 'qca'
+	 */
+	QCA_EXPORT QString appName();
+
+	/**
+	 * Set the application name that will be used by SASL server mode
+	 *
+	 * The application name is used by SASL in server mode, as some systems might
+	 * have different security policies depending on the app. This should be set 
+	 * before using SASL objects, and it cannot be changed later.
+	 *
+	 * \param name the name string to use for SASL server mode
+	 */
+	QCA_EXPORT void setAppName(const QString &name);
+
+	/**
+	 * Convert a byte array to printable hexadecimal
+	 * representation.
+	 *
+	 * This is a convenience function to convert an arbitrary
+	 * QSecureArray to a printable representation.
+	 *
+	 * \code
+	 * 	QSecureArray test(10);
+	 *	test.fill('a');
+	 * 	// 0x61 is 'a' in ASCII
+	 *	if (QString("61616161616161616161") == QCA::arrayToHex(test) ) {
+	 *		printf ("arrayToHex passed\n");
+	 *	}
+	 * \endcode
+	 *
+	 * \param array the array to be converted
+	 * \return a printable representation
+	 */
+	QCA_EXPORT QString arrayToHex(const QSecureArray &array);
+
+	/**
+	 * Convert a QString containing a hexadecimal representation
+	 * of a byte array into a QByteArray
+	 *
+	 * This is a convenience function to convert a printable
+	 * representation into a QByteArray - effectively the inverse
+	 * of QCA::arrayToHex.
+	 *
+	 * \code
+	 * 	QCA::init();
+	 * 	QByteArray test(10);
+	 *
+	 *	test.fill('b'); // 0x62 in hexadecimal
+	 *	test[7] = 0x00; // can handle strings with nulls
+	 *
+	 *	if (QCA::hexToArray(QString("62626262626262006262") ) == test ) {
+	 *		printf ("hexToArray passed\n");
+	 *	}
+	 * \endcode
+	 *
+	 * \param hexString the string containing a printable
+	 * representation to be converted
+	 * \return the equivalent QByteArray
+	 *
+	 */
+	QCA_EXPORT QByteArray hexToArray(const QString &hexString);
+
+	/**
+	 * Convenience method for initialising and cleaning up %QCA
+	 *
+	 * To ensure that QCA is properly initialised and cleaned up,
+	 * it is convenient to create an Initializer object, and let it
+	 * go out of scope at the end of %QCA usage.
+	 */
+	class QCA_EXPORT Initializer
+	{
+	public:
+		/**
+		 * Standard constructor
+		 *
+		 * \param m the MemoryMode to use for secure memory
+		 * \param prealloc the amount of secure memory to pre-allocate,
+		 *        in units of 1024 bytes (1K).
+		 */
+		Initializer(MemoryMode m = Practical, int prealloc = 64);
+		~Initializer();
+	};
+
+	/**
+	 * Simple container for acceptable key lengths
+	 *
+	 * The KeyLength specifies the minimum and maximum byte sizes
+	 * allowed for a key, as well as a "multiple" which the key
+	 * size must evenly divide into.
+	 * 
+	 * As an example, if the key can be 4, 8 or 12 bytes, you can
+	 * express this as 
+	 * \code
+	 * KeyLength keyLen( 4, 12, 4 );
+	 * \endcode
+	 * 
+	 * If you want to express a KeyLength that takes any number
+	 * of bytes (including zero), you may want to use
+	 * \code
+	 * #include<limits>
+	 * KeyLength( 0, std::numeric_limits<int>::max(), 1 );
+	 * \endcode
+	 */
+	class QCA_EXPORT KeyLength
+	{
+	public:
+		/**
+		 * Construct a %KeyLength object
+		 *
+		 * \param min the minimum length of the key, in bytes
+		 * \param max the maximum length of the key, in bytes
+		 * \param multiple the number of bytes that the key must be a 
+		 * multiple of.
+		 */
+		KeyLength(int min, int max, int multiple)
+			: _min( min ), _max(max), _multiple( multiple )
+		{ }
+		/**
+		 * Obtain the minimum length for the key, in bytes
+		 */
+		int minimum() const { return _min; }
+
+		/**
+		 * Obtain the maximum length for the key, in bytes
+		 */
+		int maximum() const { return _max; }
+
+		/**
+		 * Return the number of bytes that the key must be a multiple of
+		 *
+		 * If this is one, then anything between minumum and maximum (inclusive)
+		 * is acceptable.
+		 */
+		int multiple() const { return _multiple; }
+
+	private:
+		int const _min, _max, _multiple;
+	};
+
+	/**
+	 * Algorithm provider
+	 *
+	 * %Provider represents a plugin provider (or as a special case, the
+	 * built-in provider). This is the class you need to inherit
+	 * from to create your own plugin. You don't normally need to 
+	 * worry about this class if you are just using existing 
+	 * QCA capabilities and plugins, however there is nothing stopping
+	 * you from using it to obtain information about specific plugins,
+	 * as shown in the example below.
+	 */
+	class QCA_EXPORT Provider
+	{
+	public:
+		virtual ~Provider();
+
+		class Context
+		{
+		public:
+			Context(Provider *parent, const QString &type);
+			virtual ~Context();
+
+			Provider *provider() const;
+			QString type() const;
+			virtual Context *clone() const = 0;
+			bool sameProvider(Context *c);
+
+			int refs;
+
+		private:
+			Provider *_provider;
+			QString _type;
+		};
+
+		/**
+		 * Initialisation routine.
+		 * 
+		 * This routine will be called when your plugin
+		 * is loaded, so this is a good place to do any
+		 * one-off initialisation tasks. If you don't need
+		 * any initialisation, just implement it as an empty
+		 * routine.
+		 */
+		virtual void init();
+
+		/**
+		 * The name of the provider.
+		 * 
+		 * Typically you just return a string containing a 
+		 * convenient name.
+		 *
+		 * \code
+		 * QString name() const
+		 * {
+		 *        return "qca-myplugin";
+		 * }
+		 * \endcode
+		 *
+		 * \note  The name is used to tell if a provider is
+		 * already loaded, so you need to make sure it is
+		 * unique amongst the various plugins.
+		 */
+		virtual QString name() const = 0;
+
+		/**
+		 * The capabilities (algorithms) of the provider.
+		 *
+		 * Typically you just return a fixed QStringList:
+		 * \code
+		 * QStringList features() const
+		 * {
+		 *      QStringList list;
+		 *      list += "sha1";
+		 *      list += "sha256";
+		 *      list += "hmac(md5)";
+		 *      return list;
+		 * }
+		 * \endcode
+		 */
+		virtual QStringList features() const = 0;
+
+		/**
+		 * Routine to create a plugin context
+		 *
+		 * You need to return a pointer to an algorithm
+		 * Context that corresponds with the algorithm
+		 * name specified. 
+		 *
+		 * \param type the name of the algorithm required
+		 *
+		 * \code
+		 * Context *createContext(const QString &type)
+		 * {
+		 * if ( type == "sha1" )
+		 *     return new SHA1Context( this );
+		 * else if ( type == "sha256" )
+		 *     return new SHA0256Context( this );
+		 * else if ( type == "hmac(sha1)" )
+		 *     return new HMACSHA1Context( this );
+		 * else
+		 *     return 0;
+		 * }
+		 * \endcode
+		 * 
+		 * Naturally you also need to implement
+		 * the specified Context subclasses as well.
+		 */
+		virtual Context *createContext(const QString &type) = 0;
+	};
+
+	/**
+	 General superclass for buffered computation algorithms
+
+	 A buffered computation is characterised by having the
+	 algorithm take data in an incremental way, then having
+	 the results delivered at the end. Conceptually, the
+	 algorithm has some internal state that is modified
+	 when you call update() and returned when you call
+	 final().
+	*/
+	class QCA_EXPORT BufferedComputation
+	{
+	public:
+		virtual ~BufferedComputation();
+
+		/**
+		   Reset the internal state
+		*/
+		virtual void clear() = 0;
+
+		/**
+		   Update the internal state with a byte array
+
+		   \param a the byte array of data that is to 
+		   be used to update the internal state.
+		*/
+		virtual void update(const QSecureArray &a) = 0;
+
+		/**
+		   Complete the algorithm and return the internal state
+		*/
+		virtual QSecureArray final() = 0;
+
+		/**
+		   Perform an "all in one" update, returning
+		   the result. This is appropriate if you
+		   have all the data in one array - just
+		   call process on that array, and you will
+		   get back the results of the computation.
+
+		   \note This will invalidate any previous
+		   computation using this object.
+		*/
+		QSecureArray process(const QSecureArray &a);
+	};
+
+	/**
+	 General superclass for filtering transformation algorithms
+
+	 A filtering computation is characterised by having the
+	 algorithm take input data in an incremental way, with results
+	 delivered for each input, or block of input. Some internal
+	 state may be managed, with the transformation completed
+	 when final() is called. 
+	*/
+	class QCA_EXPORT Filter
+	{
+	public:
+		virtual ~Filter();
+
+		virtual void clear() = 0;
+		virtual QSecureArray update(const QSecureArray &a) = 0;
+		virtual QSecureArray final() = 0;
+		virtual bool ok() const = 0;
+		QSecureArray process(const QSecureArray &a);
+	};
+
+	/**
+	 General superclass for an algorithm
+	*/
+	class QCA_EXPORT Algorithm
+	{
+	public:
+		Algorithm(const Algorithm &from);
+		virtual ~Algorithm();
+
+		/**
+		   Assignment operator
+		   
+		   \param from the Algorithm to copy state from
+		*/
+		Algorithm & operator=(const Algorithm &from);
+
+		/**
+		   The type of algorithm
+		*/
+		QString type() const;
+
+		/**
+		 The name of the provider
+
+		 Each algorithm is implemented by a provider. This
+		 allows you to figure out which provider is associated
+		*/
+		Provider *provider() const;
+
+	protected:
+		Algorithm();
+		Algorithm(const QString &type, const QString &provider);
+		Provider::Context *context() const;
+		void change(Provider::Context *c);
+		void change(const QString &type, const QString &provider);
+		void detach();
+
+	private:
+		class Private;
+		Private *d;
+	};
+
+	/**
+	 * Container for keys for symmetric encryption algorithms.
+	 */
+	class QCA_EXPORT SymmetricKey : public QSecureArray
+	{
+	public:
+		/**
+		 * Construct an empty (zero length) key
+		 */
+		SymmetricKey();
+
+		/**
+		 * Construct an key of specified size, with random contents
+		 *
+		 * This is intended to be used as a random session key.
+		 *
+		 * \param size the number of bytes for the key
+		 *
+		 */
+		SymmetricKey(int size);
+
+		/**
+		 * Construct a key from a provided byte array
+		 *
+		 * \param a the byte array to copy
+		 */
+		SymmetricKey(const QSecureArray &a);
+
+		/**
+		 * Construct a key from a provided string
+		 *
+		 * \param cs the QCString to copy
+		 */
+		SymmetricKey(const QCString &cs);
+
+		/**
+		 * Test for weak DES keys
+		 *
+		 * \return true if the key is a weak key for DES
+		 */
+		bool isWeakDESKey();
+	};
+
+	/**
+	 * Container for initialisation vectors and nonces
+	 */
+	class QCA_EXPORT InitializationVector : public QSecureArray
+	{
+	public:
+		/** 
+		 * Construct an empty (zero length) initisation vector
+		 */
+		InitializationVector();
+
+		/**
+		 * Construct an initialisation vector of the specified size
+		 *
+		 * \param size the length of the initialisation vector, in bytes
+		 */
+		InitializationVector(int size);
+
+		/**
+		 * Construct an initialisation vector from a provided byte array
+		 *
+		 * \param a the byte array to copy
+		 */
+		InitializationVector(const QSecureArray &a);
+
+		/**
+		 * Construct an initialisaton vector from a provided string
+		 *
+		 * \param cs the QCString to copy
+		 */
+		InitializationVector(const QCString &cs);
+	};
+}
+
+#endif
diff --git a/include/QtCrypto/qca_export.h b/include/QtCrypto/qca_export.h
new file mode 100644
index 00000000..7b2e5e6a
--- /dev/null
+++ b/include/QtCrypto/qca_export.h
@@ -0,0 +1,50 @@
+/*
+ * qca_export.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_EXPORT_H
+#define QCA_EXPORT_H
+
+#include <qglobal.h>
+
+#ifdef Q_OS_WIN32
+# ifndef QCA_STATIC
+#  ifdef QCA_MAKEDLL
+#   define QCA_EXPORT __declspec(dllexport)
+#  else
+#   define QCA_EXPORT __declspec(dllimport)
+#  endif
+# endif
+#endif
+#ifndef QCA_EXPORT
+# define QCA_EXPORT
+#endif
+
+#ifdef Q_OS_WIN32
+# ifdef QCA_PLUGIN_DLL
+#  define QCA_PLUGIN_EXPORT extern "C" __declspec(dllexport)
+# else
+#  define QCA_PLUGIN_EXPORT extern "C" __declspec(dllimport)
+# endif
+#endif
+#ifndef QCA_PLUGIN_EXPORT
+# define QCA_PLUGIN_EXPORT extern "C"
+#endif
+
+#endif
diff --git a/include/QtCrypto/qca_publickey.h b/include/QtCrypto/qca_publickey.h
new file mode 100644
index 00000000..a320fe64
--- /dev/null
+++ b/include/QtCrypto/qca_publickey.h
@@ -0,0 +1,247 @@
+/*
+ * qca_publickey.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_PUBLICKEY_H
+#define QCA_PUBLICKEY_H
+
+#include <qobject.h>
+#include "qca_core.h"
+
+namespace QCA
+{
+	class PublicKey;
+	class PrivateKey;
+	class KeyGenerator;
+	class RSAPublicKey;
+	class RSAPrivateKey;
+	class DSAPublicKey;
+	class DSAPrivateKey;
+	class DHPublicKey;
+	class DHPrivateKey;
+
+	class QCA_EXPORT PKey : public Algorithm
+	{
+	public:
+		enum Type { RSA, DSA, DH };
+
+		PKey();
+		PKey(const PKey &from);
+		~PKey();
+
+		PKey & operator=(const PKey &from);
+
+		bool isNull() const;
+		Type type() const;
+
+		bool isRSA() const;
+		bool isDSA() const;
+		bool isDH() const;
+
+		bool isPublic() const;
+		bool isPrivate() const;
+
+		bool canKeyAgree() const;
+
+		PublicKey toPublicKey() const;
+		PrivateKey toPrivateKey() const;
+
+		friend class KeyGenerator;
+
+	protected:
+		PKey(const QString &type, const QString &provider);
+		void set(const PKey &k);
+
+		RSAPublicKey toRSAPublicKey() const;
+		RSAPrivateKey toRSAPrivateKey() const;
+		DSAPublicKey toDSAPublicKey() const;
+		DSAPrivateKey toDSAPrivateKey() const;
+		DHPublicKey toDHPublicKey() const;
+		DHPrivateKey toDHPrivateKey() const;
+
+	private:
+		class Private;
+		Private *d;
+	};
+
+	class QCA_EXPORT PublicKey : public PKey
+	{
+	public:
+		PublicKey();
+		PublicKey(const PrivateKey &k);
+
+		RSAPublicKey toRSA() const;
+		DSAPublicKey toDSA() const;
+		DHPublicKey toDH() const;
+
+		bool canEncrypt() const;
+		bool canVerify() const;
+
+		// encrypt / verify
+		int maximumEncryptSize(EncAlgo alg) const;
+		QSecureArray encrypt(EncAlgo alg, const QSecureArray &a);
+		void startVerify(SignAlgo alg);
+		void update(const QSecureArray &a);
+		bool validSignature(const QSecureArray &sig);
+		bool verifyMessage(SignAlgo alg, const QSecureArray &a, const QSecureArray &sig);
+
+		// import / export
+		QSecureArray toDER() const;
+		QString toPEM() const;
+		static PublicKey fromDER(const QSecureArray &a, const QString &provider = QString() );
+		static PublicKey fromPEM(const QString &s, const QString &provider = QString() );
+
+	protected:
+		PublicKey(const QString &type, const QString &provider);
+
+	private:
+		friend class PrivateKey;
+		friend class Certificate;
+	};
+
+	class QCA_EXPORT PrivateKey : public PKey
+	{
+	public:
+		PrivateKey();
+
+		RSAPrivateKey toRSA() const;
+		DSAPrivateKey toDSA() const;
+		DHPrivateKey toDH() const;
+
+		bool canDecrypt() const;
+		bool canSign() const;
+
+		// decrypt / sign / key agreement
+		bool decrypt(EncAlgo alg, const QSecureArray &in, QSecureArray *out);
+		void startSign(SignAlgo alg);
+		void update(const QSecureArray &);
+		QSecureArray signature();
+		QSecureArray signMessage(SignAlgo alg, const QSecureArray &a);
+		SymmetricKey deriveKey(const PublicKey &theirs);
+
+		// import / export
+		QSecureArray toDER(const QString &passphrase = QString() ) const;
+		QString toPEM(const QString &passphrase = QString() ) const;
+		static PrivateKey fromDER(const QSecureArray &a, const QString &passphrase = QString(), const QString &provider = QString() );
+		static PrivateKey fromPEM(const QString &s, const QString &passphrase = QString(), const QString &provider = QString() );
+
+	protected:
+		PrivateKey(const QString &type, const QString &provider);
+
+	private:
+		friend class TLS;
+	};
+
+	class QCA_EXPORT KeyGenerator : public QObject
+	{
+		Q_OBJECT
+	public:
+		KeyGenerator(QObject *parent = 0, const char *name = 0);
+		~KeyGenerator();
+
+		bool blocking() const;
+		void setBlocking(bool b);
+		bool isBusy() const;
+
+		void generateRSA(int bits, int exp = 65537, const QString &provider = QString() );
+		void generateDSA(DL_Group group, const QString &provider = QString() );
+		void generateDH(DL_Group group, const QString &provider = QString() );
+		PrivateKey result() const;
+
+	signals:
+		void finished();
+
+	private:
+		void done();
+
+		class Private;
+		Private *d;
+	};
+
+	class QCA_EXPORT RSAPublicKey : public PublicKey
+	{
+	public:
+		RSAPublicKey();
+		RSAPublicKey(const QBigInteger &n, const QBigInteger &e, const QString &provider = QString() );
+		RSAPublicKey(const RSAPrivateKey &k);
+
+		QBigInteger n() const;
+		QBigInteger e() const;
+	};
+
+	class QCA_EXPORT RSAPrivateKey : public PrivateKey
+	{
+	public:
+		RSAPrivateKey();
+		RSAPrivateKey(const QBigInteger &p, const QBigInteger &q, const QBigInteger &d, const QBigInteger &n, const QBigInteger &e, const QString &provider = QString() );
+
+		QBigInteger p() const;
+		QBigInteger q() const;
+		QBigInteger d() const;
+		QBigInteger n() const;
+		QBigInteger e() const;
+	};
+
+	class QCA_EXPORT DSAPublicKey : public PublicKey
+	{
+	public:
+		DSAPublicKey();
+		DSAPublicKey(DL_Group group, const QBigInteger &y, const QString &provider = QString() );
+		DSAPublicKey(const DSAPrivateKey &k);
+
+		DL_Group domain() const;
+		QBigInteger y() const;
+	};
+
+	class QCA_EXPORT DSAPrivateKey : public PrivateKey
+	{
+	public:
+		DSAPrivateKey();
+		DSAPrivateKey(DL_Group group, const QBigInteger &x, const QBigInteger &y, const QString &provider = QString() );
+
+		DL_Group domain() const;
+		QBigInteger x() const;
+		QBigInteger y() const;
+	};
+
+	class QCA_EXPORT DHPublicKey : public PublicKey
+	{
+	public:
+		DHPublicKey();
+		DHPublicKey(DL_Group group, const QBigInteger &y, const QString &provider = QString() );
+		DHPublicKey(const DHPrivateKey &k);
+
+		DL_Group domain() const;
+		QBigInteger y() const;
+	};
+
+	class QCA_EXPORT DHPrivateKey : public PrivateKey
+	{
+	public:
+		DHPrivateKey();
+		DHPrivateKey(DL_Group group, const QBigInteger &x, const QBigInteger &y, const QString &provider = QString() );
+
+		DL_Group domain() const;
+		QBigInteger x() const;
+		QBigInteger y() const;
+	};
+}
+
+#endif
diff --git a/include/QtCrypto/qca_securelayer.h b/include/QtCrypto/qca_securelayer.h
new file mode 100644
index 00000000..0b73c3d8
--- /dev/null
+++ b/include/QtCrypto/qca_securelayer.h
@@ -0,0 +1,246 @@
+/*
+ * qca_securelayer.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_SECURELAYER_H
+#define QCA_SECURELAYER_H
+
+#include <qobject.h>
+#include "qca_core.h"
+
+class QHostAddress;
+
+namespace QCA
+{
+	class PrivateKey;
+	class Certificate;
+	class Store;
+
+	// securefilter basic rule: after calling a function that might
+	//  affect something, call others to get the results.
+	//
+	// write: call readOutgoing
+	// writeIncoming: call haveClosed/haveError, read, and readOutgoing
+	// close: call haveClosed/haveError and readOutgoing
+	// haveClosed: if Closed, call readUnprocessed
+	class QCA_EXPORT SecureFilter
+	{
+	public:
+		virtual ~SecureFilter();
+
+		virtual bool isClosable() const;
+		virtual bool haveClosed() const;
+		virtual bool haveError() const = 0;
+		virtual int bytesAvailable() const = 0;
+		virtual int bytesOutgoingAvailable() const = 0;
+		virtual void close();
+
+		// plain (application side)
+		virtual void write(const QSecureArray &a) = 0;
+		virtual QSecureArray read() = 0;
+
+		// encoded (network side)
+		virtual void writeIncoming(const QByteArray &a) = 0;
+		virtual QByteArray readOutgoing(int *plainBytes = 0) = 0;
+		virtual QSecureArray readUnprocessed();
+	};
+
+	// securelayer - "nicer" interface, using signals.  subclass
+	//  should call layerUpdateBegin/End before and after write,
+	//  writeIncoming, or close.
+	class QCA_EXPORT SecureLayer : public QObject, public SecureFilter
+	{
+		Q_OBJECT
+	public:
+		SecureLayer(QObject *parent = 0, const char *name = 0);
+
+		void setStatefulOnly(bool b);
+
+	protected:
+		void layerUpdateBegin();
+		void layerUpdateEnd();
+
+	signals:
+		void readyRead();
+		void readyReadOutgoing();
+		void closed();
+		void error();
+
+	private:
+		bool _signals;
+		int _read, _readout;
+		bool _closed, _error;
+	};
+
+	class QCA_EXPORT TLS : public SecureLayer, public Algorithm
+	{
+		Q_OBJECT
+	public:
+		enum Error
+		{
+			ErrHandshake, ///< problem during the negotiation
+			ErrCrypt      ///< problem at anytime after
+		};
+		enum IdentityResult
+		{
+			Valid,        ///< identity is verified
+			HostMismatch, ///< valid cert provided, but wrong owner
+			BadCert,      ///< invalid cert
+			NoCert        ///< identity unknown
+		};
+
+		TLS(QObject *parent = 0, const char *name = 0, const QString &provider = QString() );
+		~TLS();
+
+		void reset();
+
+		void setCertificate(const Certificate &cert, const PrivateKey &key);
+		void setStore(const Store &store);
+		void setConstraints(SecurityLevel s);
+		void setConstraints(int minSSF, int maxSSF);
+
+		bool canCompress() const;
+		void setCompressionEnabled(bool b);
+
+		bool startClient(const QString &host = QString() );
+		bool startServer();
+		bool isHandshaken() const;
+		QString cipherName() const;
+		int cipherBits() const;
+		Error errorCode() const;
+
+		IdentityResult peerIdentityResult() const;
+		CertValidity peerCertificateValidity() const;
+		Certificate localCertificate() const;
+		Certificate peerCertificate() const;
+
+		// reimplemented
+		virtual bool isClosable() const;
+		virtual bool haveClosed() const;
+		virtual bool haveError() const;
+		virtual int bytesAvailable() const;
+		virtual int bytesOutgoingAvailable() const;
+		virtual void close();
+		virtual void write(const QSecureArray &a);
+		virtual QSecureArray read();
+		virtual void writeIncoming(const QByteArray &a);
+		virtual QByteArray readOutgoing(int *plainBytes = 0);
+		virtual QSecureArray readUnprocessed();
+
+	signals:
+		void handshaken();
+
+	public:
+		class Private;
+	private:
+		friend class Private;
+		Private *d;
+	};
+
+	class QCA_EXPORT SASL : public SecureLayer, public Algorithm
+	{
+		Q_OBJECT
+	public:
+		enum Error
+		{
+			ErrAuth, ///< problem during the authentication process
+			ErrCrypt ///< problem at anytime after
+		};
+		enum AuthCondition
+		{
+			NoMech,
+			BadProto,
+			BadServ,
+			BadAuth,
+			NoAuthzid,
+			TooWeak,
+			NeedEncrypt,
+			Expired,
+			Disabled,
+			NoUser,
+			RemoteUnavail
+		};
+		enum AuthFlags
+		{
+			AllowPlain             = 0x01,
+			AllowAnonymous         = 0x02,
+			RequireForwardSecrecy  = 0x04,
+			RequirePassCredentials = 0x08,
+			RequireMutualAuth      = 0x10,
+			RequireAuthzidSupport  = 0x20  // server-only
+		};
+
+		SASL(QObject *parent = 0, const char *name = 0, const QString &provider = QString() );
+		~SASL();
+
+		void reset();
+
+		// configuration
+		void setConstraints(AuthFlags f, SecurityLevel s = SL_None);
+		void setConstraints(AuthFlags f, int minSSF, int maxSSF);
+		void setLocalAddr(const QHostAddress &addr, Q_UINT16 port);
+		void setRemoteAddr(const QHostAddress &addr, Q_UINT16 port);
+		void setExternalAuthId(const QString &authid);
+		void setExternalSSF(int);
+
+		// main
+		bool startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst = true);
+		bool startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist, bool allowServerSendLast = false);
+		void putStep(const QByteArray &stepData);
+		void putServerFirstStep(const QString &mech);
+		void putServerFirstStep(const QString &mech, const QByteArray &clientInit);
+		int ssf() const;
+		Error errorCode() const;
+		AuthCondition authCondition() const;
+
+		// authentication
+		void setUsername(const QString &user);
+		void setAuthzid(const QString &auth);
+		void setPassword(const QSecureArray &pass);
+		void setRealm(const QString &realm);
+		void continueAfterParams();
+		void continueAfterAuthCheck();
+
+		// reimplemented
+		virtual bool haveError() const;
+		virtual int bytesAvailable() const;
+		virtual int bytesOutgoingAvailable() const;
+		virtual void close();
+		virtual void write(const QSecureArray &a);
+		virtual QSecureArray read();
+		virtual void writeIncoming(const QByteArray &a);
+		virtual QByteArray readOutgoing(int *plainBytes = 0);
+
+	signals:
+		void clientFirstStep(const QString &mech, const QByteArray *clientInit);
+		void nextStep(const QByteArray &stepData);
+		void needParams(bool user, bool authzid, bool pass, bool realm);
+		void authCheck(const QString &user, const QString &authzid);
+		void authenticated();
+
+	public:
+		class Private;
+	private:
+		friend class Private;
+		Private *d;
+	};
+}
+
+#endif
diff --git a/include/QtCrypto/qca_textfilter.h b/include/QtCrypto/qca_textfilter.h
new file mode 100644
index 00000000..f882825a
--- /dev/null
+++ b/include/QtCrypto/qca_textfilter.h
@@ -0,0 +1,78 @@
+/*
+ * qca_textfilter.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_TEXTFILTER_H
+#define QCA_TEXTFILTER_H
+
+#include "qca_core.h"
+
+namespace QCA
+{
+	class QCA_EXPORT TextFilter : public Filter
+	{
+	public:
+		TextFilter(Direction dir);
+
+		void setup(Direction dir);
+		QSecureArray encode(const QSecureArray &a);
+		QSecureArray decode(const QSecureArray &a);
+		QString arrayToString(const QSecureArray &a);
+		QSecureArray stringToArray(const QString &s);
+		QString encodeString(const QString &s);
+		QString decodeString(const QString &s);
+
+	protected:
+		Direction _dir;
+	};
+
+	class QCA_EXPORT Hex : public TextFilter
+	{
+	public:
+		Hex(Direction dir = Encode);
+
+		virtual void clear();
+		virtual QSecureArray update(const QSecureArray &a);
+		virtual QSecureArray final();
+		virtual bool ok() const;
+
+	private:
+		uchar val;
+		bool partial;
+		bool _ok;
+	};
+
+	class QCA_EXPORT Base64 : public TextFilter
+	{
+	public:
+		Base64(Direction dir = Encode);
+
+		virtual void clear();
+		virtual QSecureArray update(const QSecureArray &a);
+		virtual QSecureArray final();
+		virtual bool ok() const;
+
+	private:
+		QSecureArray partial;
+		bool _ok;
+	};
+}
+
+#endif
diff --git a/include/QtCrypto/qca_tools.h b/include/QtCrypto/qca_tools.h
new file mode 100644
index 00000000..631325bd
--- /dev/null
+++ b/include/QtCrypto/qca_tools.h
@@ -0,0 +1,526 @@
+/*
+ * qca_tools.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef QCA_TOOLS_H
+#define QCA_TOOLS_H
+
+#include "qca_export.h"
+#include <qcstring.h>
+#include <qstring.h>
+
+/**
+ * Secure array of bytes
+ *
+ * The %QSecureArray provides an array of memory from a pool that is,
+ * at least partly, secure. In this sense, secure means that the contents
+ * of the memory should not be made available to other applications. By
+ * comparison, a QMemArray (or subclass such as QCString or QByteArray) may
+ * be held in pages that might be swapped to disk or free'd without being
+ * cleared first.
+ *
+ * Note that this class is implicitly shared (that is, copy on write).
+ **/ 
+class QCA_EXPORT QSecureArray
+{
+public:
+	/**
+	 * Construct a secure byte array, zero length
+	 */
+	QSecureArray();
+
+	/**
+	 * Construct a secure byte array of the specified length
+	 *
+	 * \param size the number of bytes in the array
+	 */
+	QSecureArray(int size);
+
+	/**
+	 * Construct a secure byte array from a QByteArray
+	 *
+	 * Note that this copies, rather than references the source array
+	 *
+	 * \sa operator=()
+	 */
+	QSecureArray(const QByteArray &a);
+
+	/**
+	 * Construct a secure byte array from a string
+	 *
+	 * Note that this copies, rather than references the source array
+	 *
+	 * \sa operator=()
+	 */
+	QSecureArray(const QCString &cs);
+
+	/**
+	 * Construct a (shallow) copy of another secure byte array
+	 *
+	 * \param from the source of the data and length.
+	 */
+	QSecureArray(const QSecureArray &from);
+
+	~QSecureArray();
+
+	/** 
+	 * Creates a reference, rather than a deep copy.
+	 * if you want a deep copy then you should use copy()
+	 * instead, or use operator=(), then call detach() when required.
+	 */
+	QSecureArray & operator=(const QSecureArray &from);
+
+	/**
+	 * Creates a copy, rather than references
+	 *
+	 * \param a the array to copy from
+	 */
+	QSecureArray & operator=(const QByteArray &a);
+
+	/**
+	 * Creates a copy, rather than references
+	 *
+	 * \param cs the string to copy from
+	 */
+	QSecureArray & operator=(const QCString &cs);
+
+	/**
+	 * Returns a reference to the byte at the index position
+	 *
+	 * \param index the zero-based offset to obtain
+	 */
+	char & operator[](int index);
+
+	/**
+	 * Returns a reference to the byte at the index position
+	 *
+	 * \param index the zero-based offset to obtain
+	 */
+	const char & operator[](int index) const;
+
+	/**
+	 * Pointer to the data in the secure array
+	 * 
+	 * You can use this for memcpy and similar functions. If you are trying
+	 * to obtain data at a particular offset, you might be better off using
+	 * at() or operator[]
+	 *
+	 */
+	const char *data() const;
+
+	/**
+	 * Pointer to the data in the secure array
+	 * 
+	 * You can use this for memcpy and similar functions. If you are trying
+	 * to obtain data at a particular offset, you might be better off using
+	 * at() or operator[]
+	 *
+	 */
+	char *data();
+
+	/**
+	 * Returns a reference to the byte at the index position
+	 *
+	 * \param index the zero-based offset to obtain
+	 */
+	const char & at(uint index) const;
+
+	/**
+	 * Returns a reference to the byte at the index position
+	 *
+	 * \param index the zero-based offset to obtain
+	 */
+	char & at(uint index);
+
+	/**
+	 * Returns the number of bytes in the array
+	 */
+	uint size() const;
+
+	/**
+	 * Test if the array contains any bytes.
+	 * 
+	 * This is equivalent to testing (size() != 0). Note that if
+	 * the array is allocated, isEmpty() is false (even if no data
+	 * has been added)
+	 *
+	 * \return true if the array has zero length, otherwise false
+	 */
+	bool isEmpty() const;
+
+	/**
+	 * Change the length of this array
+	 * If the new length is less than the old length, the extra information
+	 * is (safely) discarded. If the new length is equal to or greater than
+	 * the old length, the existing data is copied into the array.
+	 *
+	 * \param size the new length
+	 */
+	bool resize(uint size);
+
+        /**
+         * Fill the data array with a specified character
+	 *
+	 * \param fillChar the character to use as the fill
+	 * \param fillToPosition the number of characters to fill
+	 *        to. If not specified (or -1), fills array to
+	 *        current length.
+	 *
+	 * \note This function does not extend the array - if
+	 * you ask for fill beyond the current length, only
+	 * the current length will be used.
+	 * \note The number of characters is 1 based, so if
+	 * you ask for fill('x', 10), it will fill from
+	 * 
+         */
+        void fill(char fillChar, int fillToPosition = -1);
+
+	/** 
+	 * creates a deep copy, rather than a reference
+	 * if you want a reference then you should use operator=()
+	 */
+	QSecureArray copy() const;
+
+	/**
+	 * If the current array is shared, this conducts a deep copy, 
+	 * otherwise it has no effect.
+	 *
+	 * \code
+	 * QSecureArray myArray = anotherArray; // currently the same
+	 * myArray.detach(); // no longer the same data, but a copy
+	 * // anything here that affects anotherArray does not affect
+	 * // myArray; and vice versa.
+	 * \endcode
+	 */
+	void detach();
+
+	 /**
+	  * Copy the contents of the secure array out to a 
+	  * standard QByteArray. Note that this performs a deep copy
+	  * of the data.
+	  */
+	QByteArray toByteArray() const;
+
+	/**
+	 * Append a secure byte array to the end of this array
+	 */
+	QSecureArray & append(const QSecureArray &a);
+protected:
+	/**
+	 * Assign the contents of a provided byte array to this
+	 * object.
+	 *
+	 * \param from the byte array to copy
+	 */
+	void set(const QSecureArray &from);
+	/**
+	 * Assign the contents of a provided string to this
+	 * object.
+	 *
+	 * \param cs the QCString to copy
+	 */
+	void set(const QCString &cs);
+
+private:
+	class Private;
+	Private *d;
+
+	void reset();
+};
+
+/**
+ * Equality operator. Returns true if the two QSecureArray
+ * arguments have the same data (and the same length, of course).
+ *
+ * \relates QSecureArray
+ **/
+QCA_EXPORT bool operator==(const QSecureArray &a, const QSecureArray &b);
+
+/**
+ * Inequality operator. Returns true if the two QSecureArray
+ * arguments have different length, or the same length but
+ * different data
+ *
+ * \relates QSecureArray
+ **/
+QCA_EXPORT bool operator!=(const QSecureArray &a, const QSecureArray &b);
+
+/**
+ * Arbitrary precision integer
+ *
+ * %QBigInteger provides arbitrary precision integers.
+ * \code
+ * if ( QBigInteger("3499543804349") == 
+ *      QBigInteger("38493290803248") + QBigInteger( 343 ) )
+ * {
+ *       // do something
+ * }
+ * \endcode
+ *       
+ **/
+class QCA_EXPORT QBigInteger
+{
+public:
+	/**
+	 * Constructor. Creates a new QBigInteger, initialised to zero.
+	 */
+	QBigInteger();
+
+	/**
+	 * \overload
+	 *
+	 * \param n an alternative integer initialisation value.
+	 */
+	QBigInteger(int n);
+
+	/**
+	 * \overload
+	 *
+	 * \param s an alternative initialisation value, encoded as a string
+	 *
+	 * \code
+	 * QBigInteger b ( "9890343" );
+	 * \endcode
+	 */
+	QBigInteger(const QString &s);
+
+	/**
+	 * \overload
+	 *
+	 * \param a an alternative initialisation value, encoded as QSecureArray
+	 */
+	QBigInteger(const QSecureArray &a);
+
+	/**
+	 * \overload
+	 *
+	 * \param from an alternative initialisation value, encoded as a %QBigInteger
+	 */
+	QBigInteger(const QBigInteger &from);
+
+	~QBigInteger();
+
+	/**
+	 * Assignment operator
+	 * 
+	 * \param from the QBigInteger to copy from
+	 *
+	 * \code
+	 * QBigInteger a; // a is zero
+	 * QBigInteger b( 500 );
+	 * a = b; // a is now 500
+	 * \endcode
+	 */
+	QBigInteger & operator=(const QBigInteger &from);
+
+	/**
+	 * \overload
+	 *
+	 * \param s the QString containing an integer representation
+	 *
+	 * \sa bool fromString(const QString &s)
+	 *
+	 * \note it is the application's responsibility to make sure
+	 * that the QString represents a valid integer (ie it only
+	 * contains numbers and an optional minus sign at the start)
+	 * 
+	 **/
+	QBigInteger & operator=(const QString &s);
+
+	/**
+	 * Increment in place operator
+	 *
+	 * \param b the amount to increment by
+	 *
+	 * \code
+	 * QBigInteger a; // a is zero
+	 * QBigInteger b( 500 );
+	 * a += b; // a is now 500
+	 * a += b; // a is now 1000
+	 * \endcode
+	 **/
+	QBigInteger & operator+=(const QBigInteger &b);
+
+	/**
+	 * Decrement in place operator
+	 *
+	 * \param b the amount to decrement by
+	 *
+	 * \code
+	 * QBigInteger a; // a is zero
+	 * QBigInteger b( 500 );
+	 * a -= b; // a is now -500
+	 * a -= b; // a is now -1000
+	 * \endcode
+	 **/
+	QBigInteger & operator-=(const QBigInteger &b);
+
+	/** 
+	 * Output %QBigInteger as a byte array, useful for storage or
+	 * transmission.  The format is a binary integer in sign-extended
+	 * network-byte-order.
+	 *
+	 * \sa void fromArray(const QSecureArray &a);
+	 */
+	QSecureArray toArray() const;
+
+	/**
+	 * Assign from an array.  The input is expected to be a binary integer
+	 * in sign-extended network-byte-order.
+	 *
+	 * \param a a QSecureArray that represents an integer
+	 *
+	 * \sa QBigInteger(const QSecureArray &a);
+	 * \sa QSecureArray toArray() const;
+	 */
+	void fromArray(const QSecureArray &a);
+
+	/** 
+	 * Convert %QBigInteger to a QString
+	 *
+	 * \code
+	 * QString aString;
+	 * QBigInteger aBiggishInteger( 5878990 );
+	 * aString = aBiggishInteger.toString(); // aString is now "5878990"
+	 * \endcode
+	 */
+	QString toString() const;
+
+	/**
+	 * Assign from a QString
+	 *
+	 * \param s a QString that represents an integer
+	 *
+	 * \note it is the application's responsibility to make sure
+	 * that the QString represents a valid integer (ie it only
+	 * contains numbers and an optional minus sign at the start)
+	 * 
+	 * \sa QBigInteger(const QString &s)
+	 * \sa QBigInteger & operator=(const QString &s)
+	 */
+	bool fromString(const QString &s);
+
+	/** 
+	 * Compare this value with another %QBigInteger
+	 *
+	 * Normally it is more readable to use one of the operator overloads,
+	 * so you don't need to use this method directly.
+	 *
+	 * \param n the QBigInteger to compare with
+	 *
+	 * \return zero if the values are the same, negative if the argument
+	 * is less than the value of this QBigInteger, and positive if the argument
+	 * value is greater than this QBigInteger
+	 *
+	 * \code
+	 * QBigInteger a( "400" );
+	 * QBigInteger b( "-400" );
+	 * QBigInteger c( " 200 " );
+	 * int result;
+	 * result = a.compare( b );        // return positive 400 > -400
+	 * result = a.compare( c );        // return positive,  400 > 200
+	 * result = b.compare( c );        // return negative, -400 < 200
+	 * \endcode
+	 **/
+	int compare(const QBigInteger &n) const;
+
+private:
+	class Private;
+	Private *d;
+};
+
+/**
+ * Equality operator. Returns true if the two QBigInteger values
+ * are the same, including having the same sign. 
+ *
+ * \relates QBigInteger
+ **/
+inline bool operator==(const QBigInteger &a, const QBigInteger &b)
+{
+	return (0 == a.compare( b ) );
+}
+
+/**
+ * Inequality operator. Returns true if the two QBigInteger values
+ * are different in magnitude, sign or both  
+ *
+ * \relates QBigInteger
+ **/
+inline bool operator!=(const QBigInteger &a, const QBigInteger &b)
+{
+	return (0 != a.compare( b ) );
+}
+
+/**
+ * Less than or equal operator. Returns true if the QBigInteger value
+ * on the left hand side is equal to or less than the QBigInteger value
+ * on the right hand side.
+ *
+ * \relates QBigInteger
+ **/
+inline bool operator<=(const QBigInteger &a, const QBigInteger &b)
+{
+	return (a.compare( b ) <= 0 );
+}
+
+/**
+ * Greater than or equal operator. Returns true if the QBigInteger value
+ * on the left hand side is equal to or greater than the QBigInteger value
+ * on the right hand side.
+ *
+ * \relates QBigInteger
+ **/
+inline bool operator>=(const QBigInteger &a, const QBigInteger &b)
+{
+	return (a.compare( b ) >= 0 );
+}
+
+/**
+ * Less than operator. Returns true if the QBigInteger value
+ * on the left hand side is less than the QBigInteger value
+ * on the right hand side.
+ *
+ * \relates QBigInteger
+ **/
+inline bool operator<(const QBigInteger &a, const QBigInteger &b)
+{
+	return (a.compare( b ) < 0 );
+}
+
+/**
+ * Greater than operator. Returns true if the QBigInteger value
+ * on the left hand side is greater than the QBigInteger value
+ * on the right hand side.
+ *
+ * \relates QBigInteger
+ **/
+inline bool operator>(const QBigInteger &a, const QBigInteger &b)
+{
+	return (a.compare( b ) > 0 );
+}
+
+/**
+ * Stream operator.
+ *
+ * \relates QBigInteger
+ **/
+QCA_EXPORT QTextStream &operator<<(QTextStream &stream, const QBigInteger &b);
+
+#endif
diff --git a/src/qcaprovider.h b/include/QtCrypto/qcaprovider.h
similarity index 98%
rename from src/qcaprovider.h
rename to include/QtCrypto/qcaprovider.h
index a9b8e57d..157943f8 100644
--- a/src/qcaprovider.h
+++ b/include/QtCrypto/qcaprovider.h
@@ -1,6 +1,7 @@
 /*
  * qcaprovider.h - QCA Plugin API
- * Copyright (C) 2003,2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +26,8 @@
 #include <qdatetime.h>
 #include <qobject.h>
 #include <qhostaddress.h>
-#include "qca.h"
+#include "qca_core.h"
+#include "qca_basic.h"
 
 #include <limits>
 
diff --git a/qca.pro b/qca.pro
index f232d879..df83f53e 100644
--- a/qca.pro
+++ b/qca.pro
@@ -17,34 +17,51 @@ win32:{
 	DEFINES += QCA_MAKEDLL
 }
 
+QCA_INC = include/QtCrypto
 QCA_CPP = src
-INCLUDEPATH += $$QCA_CPP
+INCLUDEPATH += $$QCA_INC $$QCA_CPP
 
 # botantools
 include(src/botantools/botantools.pri)
 
 HEADERS += \
-	$$QCA_CPP/qca.h \
-	$$QCA_CPP/qcaprovider.h \
+	$$QCA_INC/qca_export.h \
+	$$QCA_INC/qca_tools.h \
+	$$QCA_INC/qca_core.h \
+	$$QCA_INC/qca_textfilter.h \
 	$$QCA_CPP/qca_plugin.h \
+	$$QCA_INC/qca_basic.h \
+	$$QCA_INC/qca_publickey.h \
+	$$QCA_INC/qca_cert.h \
+	$$QCA_INC/qca_securelayer.h \
+	$$QCA_INC/qcaprovider.h \
 	$$QCA_CPP/qca_systemstore.h
 
 SOURCES += \
-	$$QCA_CPP/qca.cpp \
-	$$QCA_CPP/qca_plugin.cpp \
 	$$QCA_CPP/qca_tools.cpp \
-	$$QCA_CPP/qca_basic.cpp \
+	$$QCA_CPP/qca_core.cpp \
 	$$QCA_CPP/qca_textfilter.cpp \
+	$$QCA_CPP/qca_plugin.cpp \
+	$$QCA_CPP/qca_basic.cpp \
 	$$QCA_CPP/qca_publickey.cpp \
 	$$QCA_CPP/qca_cert.cpp \
 	$$QCA_CPP/qca_securelayer.cpp \
 	$$QCA_CPP/qca_default.cpp
 
-#DEFINES += QCA_NO_SYSTEMSTORE
+DEFINES += QCA_NO_SYSTEMSTORE
 
-# debian cert store
-DEFINES += QCA_SYSTEMSTORE_PATH='"/etc/ssl/certs/ca-certificates.crt"'
-SOURCES += $$QCA_CPP/qca_systemstore_flatfile.cpp
+unix:!mac: {
+	# debian cert store
+	DEFINES += QCA_SYSTEMSTORE_PATH='"/etc/ssl/certs/ca-certificates.crt"'
+	SOURCES += $$QCA_CPP/qca_systemstore_flatfile.cpp
+}
+win: {
+	SOURCES += $$QCA_CPP/qca_systemstore_win.cpp
+}
+mac: {
+	SOURCES += $$QCA_CPP/qca_systemstore_mac.cpp
+	QMAKE_LFLAGS += -framework Carbon
+}
 
 include(conf.pri)
 include(extra.pri)
diff --git a/src/qca.h b/src/qca.h
deleted file mode 100644
index 8f2a8d91..00000000
--- a/src/qca.h
+++ /dev/null
@@ -1,3191 +0,0 @@
-/*
- * qca.h - Qt Cryptographic Architecture
- * Copyright (C) 2003,2004  Justin Karneges
- * Copyright (C) 2004  Brad Hards <bradh@frogmouth.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#ifndef QCA_H
-#define QCA_H
-
-#include <qstring.h>
-#include <qcstring.h>
-#include <qdatetime.h>
-#include <qmap.h>
-#include <qptrlist.h>
-#include <qobject.h>
-#include <qtextstream.h>
-
-#ifdef Q_OS_WIN32
-# ifndef QCA_STATIC
-#  ifdef QCA_MAKEDLL
-#   define QCA_EXPORT __declspec(dllexport)
-#  else
-#   define QCA_EXPORT __declspec(dllimport)
-#  endif
-# endif
-#endif
-#ifndef QCA_EXPORT
-# define QCA_EXPORT
-#endif
-
-#ifdef Q_OS_WIN32
-# ifdef QCA_PLUGIN_DLL
-#  define QCA_PLUGIN_EXPORT extern "C" __declspec(dllexport)
-# else
-#  define QCA_PLUGIN_EXPORT extern "C" __declspec(dllimport)
-# endif
-#endif
-#ifndef QCA_PLUGIN_EXPORT
-# define QCA_PLUGIN_EXPORT extern "C"
-#endif
-
-#define QCA_VERSION 0x020000
-
-class QHostAddress;
-class QStringList;
-
-class QCAProvider;
-class QCA_HashContext;
-class QCA_CipherContext;
-class QCA_CertContext;
-
-/**
-   \mainpage %Qt Cryptographic Architecture
-
-   Taking a hint from the similarly-named
-   <a href="http://java.sun.com/j2se/1.4/docs/guide/security/CryptoSpec.html">Java
-   Cryptography Architecture</a>, %QCA aims to provide a
-   straightforward and cross-platform cryptographic API, using Qt
-   datatypes and conventions.  %QCA separates the API from the
-   implementation, using plugins known as Providers.  The advantage
-   of this model is to allow applications to avoid linking to or
-   explicitly depending on any particular cryptographic library.
-   This allows one to easily change or upgrade Provider
-   implementations without even needing to recompile the
-   application!
-
-   %QCA should work everywhere %Qt does, including Windows/Unix/MacOSX.
-
-   \section features Features
-
-   This library provides an easy API for the following features:
-     - Secure byte arrays (QSecureArray)
-     - Arbitrary precision integers (QBigInteger)
-     - Random number generation (QCA::Random)
-     - SSL/TLS (ToDo)
-     - X509 certificate (Cert) (ToDo)
-     - Simple Authentication and Security Layer (SASL) (ToDo)
-     - RSA (ToDo)
-     - Hashing (QCA::Hash)
-         - QCA::SHA0
-         - QCA::SHA1
-         - QCA::MD2
-         - QCA::MD4
-         - QCA::MD5
-         - QCA::RIPEMD160
-         - QCA::SHA256
-         - QCA::SHA384
-         - QCA::SHA512
-     - Ciphers (QCA::Cipher)
-         - BlowFish  (QCA::BlowFish)
-         - Triple %DES (QCA::TripleDES)
-         - %DES (QCA::DES)
-         - AES (QCA::AES128, QCA::AES192, QCA::AES256)
-     - Keyed Hash Message Authentication Code (QCA::HMAC), using
-         - SHA1
-         - MD5
-         - RIPEMD160
-  
-   Functionality is supplied via plugins.  This is useful for avoiding
-   dependence on a particular crypto library and makes upgrading easier,
-   as there is no need to recompile your application when adding or
-   upgrading a crypto plugin.  Also, by pushing crypto functionality into
-   plugins, your application is free of legal issues, such as export
-   regulation.
- 
-   And of course, you get a very simple crypto API for Qt, where you can
-   do things like:
-   \code
-   QString hash = QCA::SHA1().hashToString(blockOfData);
-   \endcode
-
-   \section using Using QCA
-
-   The application simply includes %qca.h and links to libqca,
-   which provides the 'wrapper API' and plugin loader.  Crypto
-   functionality is determined during runtime, and plugins are
-   loaded from the 'crypto' subfolder of the %Qt library paths. There
-   are <a href="examples.html">additional examples available</a>.
-
-   \section availability Availability
-
-   \subsection qca2code Current development
-
-   The latest version of the code is available from the KDE CVS
-   server (there is no formal release of the current version at this time). See
-   <a href="http://developer.kde.org/source/anoncvs.html">
-   http://developer.kde.org/source/anoncvs.html
-   </a> for general instructions. You do <i>not</i> need kdelibs or
-   arts modules for %QCA - just pull down kdesupport/qca. The plugins
-   are in the same tree. Naturally you will need %Qt properly set up
-   and configured in order to build and use %QCA.
-
-   The CVS code can also be browsed
-   <a href="http://webcvs.kde.org/cgi-bin/cvsweb.cgi/kdesupport/qca/">
-   via the web</a>
-
-   \subsection qca1code Previous versions
-   
-   A previous version of %QCA (sometimes referred to as QCA1) is still available.
-   You will need to get the main library 
-   (<a href="src/qca1/qca-1.0.tar.bz2">qca-1.0.tar.bz2</a>) and one or
-   more providers
-   (<a href="src/qca1/qca-tls-1.0.tar.bz2">qca-tls-1.0.tar.bz2</a> for
-   the OpenSSL based provider, or
-   <a href="src/qca1/qca-sasl-1.0.tar.bz2">qca-sasl-1.0.tar.bz2</a> for
-   the SASL based provider). Note that development of QCA1 has basically
-   stopped.
-
- */
-
-// Direct secure memory access.  For interfacing with C libraries if needed.
-QCA_EXPORT void *qca_secure_alloc(int bytes);
-QCA_EXPORT void qca_secure_free(void *p);
-
-/**
- * Secure array of bytes
- *
- * The %QSecureArray provides an array of memory from a pool that is,
- * at least partly, secure. In this sense, secure means that the contents
- * of the memory should not be made available to other applications. By
- * comparison, a QMemArray (or subclass such as QCString or QByteArray) may
- * be held in pages that might be swapped to disk or free'd without being
- * cleared first.
- *
- * Note that this class is implicitly shared (that is, copy on write).
- **/ 
-QCA_EXPORT class QSecureArray
-{
-public:
-	/**
-	 * Construct a secure byte array, zero length
-	 */
-	QSecureArray();
-
-	/**
-	 * Construct a secure byte array of the specified length
-	 *
-	 * \param size the number of bytes in the array
-	 */
-	QSecureArray(int size);
-
-	/**
-	 * Construct a secure byte array from a QByteArray
-	 *
-	 * Note that this copies, rather than references the source array
-	 *
-	 * \sa operator=()
-	 */
-	QSecureArray(const QByteArray &a);
-
-	/**
-	 * Construct a secure byte array from a string
-	 *
-	 * Note that this copies, rather than references the source array
-	 *
-	 * \sa operator=()
-	 */
-	QSecureArray(const QCString &cs);
-
-	/**
-	 * Construct a (shallow) copy of another secure byte array
-	 *
-	 * \param from the source of the data and length.
-	 */
-	QSecureArray(const QSecureArray &from);
-
-	~QSecureArray();
-
-	/** 
-	 * Creates a reference, rather than a deep copy.
-	 * if you want a deep copy then you should use copy()
-	 * instead, or use operator=(), then call detach() when required.
-	 */
-	QSecureArray & operator=(const QSecureArray &from);
-
-	/**
-	 * Creates a copy, rather than references
-	 *
-	 * \param a the array to copy from
-	 */
-	QSecureArray & operator=(const QByteArray &a);
-
-	/**
-	 * Creates a copy, rather than references
-	 *
-	 * \param cs the string to copy from
-	 */
-	QSecureArray & operator=(const QCString &cs);
-
-	/**
-	 * Returns a reference to the byte at the index position
-	 *
-	 * \param index the zero-based offset to obtain
-	 */
-	char & operator[](int index);
-
-	/**
-	 * Returns a reference to the byte at the index position
-	 *
-	 * \param index the zero-based offset to obtain
-	 */
-	const char & operator[](int index) const;
-
-	/**
-	 * Pointer to the data in the secure array
-	 * 
-	 * You can use this for memcpy and similar functions. If you are trying
-	 * to obtain data at a particular offset, you might be better off using
-	 * at() or operator[]
-	 *
-	 */
-	const char *data() const;
-
-	/**
-	 * Pointer to the data in the secure array
-	 * 
-	 * You can use this for memcpy and similar functions. If you are trying
-	 * to obtain data at a particular offset, you might be better off using
-	 * at() or operator[]
-	 *
-	 */
-	char *data();
-
-	/**
-	 * Returns a reference to the byte at the index position
-	 *
-	 * \param index the zero-based offset to obtain
-	 */
-	const char & at(uint index) const;
-
-	/**
-	 * Returns a reference to the byte at the index position
-	 *
-	 * \param index the zero-based offset to obtain
-	 */
-	char & at(uint index);
-
-	/**
-	 * Returns the number of bytes in the array
-	 */
-	uint size() const;
-
-	/**
-	 * Test if the array contains any bytes.
-	 * 
-	 * This is equivalent to testing (size() != 0). Note that if
-	 * the array is allocated, isEmpty() is false (even if no data
-	 * has been added)
-	 *
-	 * \return true if the array has zero length, otherwise false
-	 */
-	bool isEmpty() const;
-
-	/**
-	 * Change the length of this array
-	 * If the new length is less than the old length, the extra information
-	 * is (safely) discarded. If the new length is equal to or greater than
-	 * the old length, the existing data is copied into the array.
-	 *
-	 * \param size the new length
-	 */
-	bool resize(uint size);
-
-        /**
-         * Fill the data array with a specified character
-	 *
-	 * \param fillChar the character to use as the fill
-	 * \param fillToPosition the number of characters to fill
-	 *        to. If not specified (or -1), fills array to
-	 *        current length.
-	 *
-	 * \note This function does not extend the array - if
-	 * you ask for fill beyond the current length, only
-	 * the current length will be used.
-	 * \note The number of characters is 1 based, so if
-	 * you ask for fill('x', 10), it will fill from
-	 * 
-         */
-        void fill(char fillChar, int fillToPosition = -1);
-
-	/** 
-	 * creates a deep copy, rather than a reference
-	 * if you want a reference then you should use operator=()
-	 */
-	QSecureArray copy() const;
-
-	/**
-	 * If the current array is shared, this conducts a deep copy, 
-	 * otherwise it has no effect.
-	 *
-	 * \code
-	 * QSecureArray myArray = anotherArray; // currently the same
-	 * myArray.detach(); // no longer the same data, but a copy
-	 * // anything here that affects anotherArray does not affect
-	 * // myArray; and vice versa.
-	 * \endcode
-	 */
-	void detach();
-
-	 /**
-	  * Copy the contents of the secure array out to a 
-	  * standard QByteArray. Note that this performs a deep copy
-	  * of the data.
-	  */
-	QByteArray toByteArray() const;
-
-	/**
-	 * Append a secure byte array to the end of this array
-	 */
-	QSecureArray & append(const QSecureArray &a);
-protected:
-	/**
-	 * Assign the contents of a provided byte array to this
-	 * object.
-	 *
-	 * \param from the byte array to copy
-	 */
-	void set(const QSecureArray &from);
-	/**
-	 * Assign the contents of a provided string to this
-	 * object.
-	 *
-	 * \param cs the QCString to copy
-	 */
-	void set(const QCString &cs);
-
-private:
-	class Private;
-	Private *d;
-
-	void reset();
-};
-
-/**
- * Equality operator. Returns true if the two QSecureArray
- * arguments have the same data (and the same length, of course).
- *
- * \relates QSecureArray
- **/
-QCA_EXPORT bool operator==(const QSecureArray &a, const QSecureArray &b);
-
-/**
- * Inequality operator. Returns true if the two QSecureArray
- * arguments have different length, or the same length but
- * different data
- *
- * \relates QSecureArray
- **/
-QCA_EXPORT bool operator!=(const QSecureArray &a, const QSecureArray &b);
-
-/**
- * Arbitrary precision integer
- *
- * %QBigInteger provides arbitrary precision integers.
- * \code
- * if ( QBigInteger("3499543804349") == 
- *      QBigInteger("38493290803248") + QBigInteger( 343 ) )
- * {
- *       // do something
- * }
- * \endcode
- *       
- **/
-QCA_EXPORT class QBigInteger
-{
-public:
-	/**
-	 * Constructor. Creates a new QBigInteger, initialised to zero.
-	 */
-	QBigInteger();
-
-	/**
-	 * \overload
-	 *
-	 * \param n an alternative integer initialisation value.
-	 */
-	QBigInteger(int n);
-
-	/**
-	 * \overload
-	 *
-	 * \param s an alternative initialisation value, encoded as a string
-	 *
-	 * \code
-	 * QBigInteger b ( "9890343" );
-	 * \endcode
-	 */
-	QBigInteger(const QString &s);
-
-	/**
-	 * \overload
-	 *
-	 * \param a an alternative initialisation value, encoded as QSecureArray
-	 */
-	QBigInteger(const QSecureArray &a);
-
-	/**
-	 * \overload
-	 *
-	 * \param from an alternative initialisation value, encoded as a %QBigInteger
-	 */
-	QBigInteger(const QBigInteger &from);
-
-	~QBigInteger();
-
-	/**
-	 * Assignment operator
-	 * 
-	 * \param from the QBigInteger to copy from
-	 *
-	 * \code
-	 * QBigInteger a; // a is zero
-	 * QBigInteger b( 500 );
-	 * a = b; // a is now 500
-	 * \endcode
-	 */
-	QBigInteger & operator=(const QBigInteger &from);
-
-	/**
-	 * \overload
-	 *
-	 * \param s the QString containing an integer representation
-	 *
-	 * \sa bool fromString(const QString &s)
-	 *
-	 * \note it is the application's responsibility to make sure
-	 * that the QString represents a valid integer (ie it only
-	 * contains numbers and an optional minus sign at the start)
-	 * 
-	 **/
-	QBigInteger & operator=(const QString &s);
-
-	/**
-	 * Increment in place operator
-	 *
-	 * \param b the amount to increment by
-	 *
-	 * \code
-	 * QBigInteger a; // a is zero
-	 * QBigInteger b( 500 );
-	 * a += b; // a is now 500
-	 * a += b; // a is now 1000
-	 * \endcode
-	 **/
-	QBigInteger & operator+=(const QBigInteger &b);
-
-	/**
-	 * Decrement in place operator
-	 *
-	 * \param b the amount to decrement by
-	 *
-	 * \code
-	 * QBigInteger a; // a is zero
-	 * QBigInteger b( 500 );
-	 * a -= b; // a is now -500
-	 * a -= b; // a is now -1000
-	 * \endcode
-	 **/
-	QBigInteger & operator-=(const QBigInteger &b);
-
-	/** 
-	 * Output %QBigInteger as a byte array, useful for storage or
-	 * transmission.  The format is a binary integer in sign-extended
-	 * network-byte-order.
-	 *
-	 * \sa void fromArray(const QSecureArray &a);
-	 */
-	QSecureArray toArray() const;
-
-	/**
-	 * Assign from an array.  The input is expected to be a binary integer
-	 * in sign-extended network-byte-order.
-	 *
-	 * \param a a QSecureArray that represents an integer
-	 *
-	 * \sa QBigInteger(const QSecureArray &a);
-	 * \sa QSecureArray toArray() const;
-	 */
-	void fromArray(const QSecureArray &a);
-
-	/** 
-	 * Convert %QBigInteger to a QString
-	 *
-	 * \code
-	 * QString aString;
-	 * QBigInteger aBiggishInteger( 5878990 );
-	 * aString = aBiggishInteger.toString(); // aString is now "5878990"
-	 * \endcode
-	 */
-	QString toString() const;
-
-	/**
-	 * Assign from a QString
-	 *
-	 * \param s a QString that represents an integer
-	 *
-	 * \note it is the application's responsibility to make sure
-	 * that the QString represents a valid integer (ie it only
-	 * contains numbers and an optional minus sign at the start)
-	 * 
-	 * \sa QBigInteger(const QString &s)
-	 * \sa QBigInteger & operator=(const QString &s)
-	 */
-	bool fromString(const QString &s);
-
-	/** 
-	 * Compare this value with another %QBigInteger
-	 *
-	 * Normally it is more readable to use one of the operator overloads,
-	 * so you don't need to use this method directly.
-	 *
-	 * \param n the QBigInteger to compare with
-	 *
-	 * \return zero if the values are the same, negative if the argument
-	 * is less than the value of this QBigInteger, and positive if the argument
-	 * value is greater than this QBigInteger
-	 *
-	 * \code
-	 * QBigInteger a( "400" );
-	 * QBigInteger b( "-400" );
-	 * QBigInteger c( " 200 " );
-	 * int result;
-	 * result = a.compare( b );        // return positive 400 > -400
-	 * result = a.compare( c );        // return positive,  400 > 200
-	 * result = b.compare( c );        // return negative, -400 < 200
-	 * \endcode
-	 **/
-	int compare(const QBigInteger &n) const;
-
-private:
-	class Private;
-	Private *d;
-};
-
-/**
- * Equality operator. Returns true if the two QBigInteger values
- * are the same, including having the same sign. 
- *
- * \relates QBigInteger
- **/
-inline bool operator==(const QBigInteger &a, const QBigInteger &b)
-{
-	return (0 == a.compare( b ) );
-}
-
-/**
- * Inequality operator. Returns true if the two QBigInteger values
- * are different in magnitude, sign or both  
- *
- * \relates QBigInteger
- **/
-inline bool operator!=(const QBigInteger &a, const QBigInteger &b)
-{
-	return (0 != a.compare( b ) );
-}
-
-/**
- * Less than or equal operator. Returns true if the QBigInteger value
- * on the left hand side is equal to or less than the QBigInteger value
- * on the right hand side.
- *
- * \relates QBigInteger
- **/
-inline bool operator<=(const QBigInteger &a, const QBigInteger &b)
-{
-	return (a.compare( b ) <= 0 );
-}
-
-/**
- * Greater than or equal operator. Returns true if the QBigInteger value
- * on the left hand side is equal to or greater than the QBigInteger value
- * on the right hand side.
- *
- * \relates QBigInteger
- **/
-inline bool operator>=(const QBigInteger &a, const QBigInteger &b)
-{
-	return (a.compare( b ) >= 0 );
-}
-
-/**
- * Less than operator. Returns true if the QBigInteger value
- * on the left hand side is less than the QBigInteger value
- * on the right hand side.
- *
- * \relates QBigInteger
- **/
-inline bool operator<(const QBigInteger &a, const QBigInteger &b)
-{
-	return (a.compare( b ) < 0 );
-}
-
-/**
- * Greater than operator. Returns true if the QBigInteger value
- * on the left hand side is greater than the QBigInteger value
- * on the right hand side.
- *
- * \relates QBigInteger
- **/
-inline bool operator>(const QBigInteger &a, const QBigInteger &b)
-{
-	return (a.compare( b ) > 0 );
-}
-
-/**
- * Stream operator.
- *
- * \relates QBigInteger
- **/
-QTextStream &operator<<(QTextStream &stream, const QBigInteger &b);
-
-/** 
- * QCA - the Qt Cryptographic Architecture
- */
-namespace QCA
-{
-	class Provider;
-	class Random;
-	class Store;
-
-	/**
-	 * Convenience representation for the plugin providers
-	 * 
-	 * You can get a list of providers using the providers()
-	 * function
-	 *
-	 * \sa ProviderListIterator
-	 * \sa providers()
-	 */
-	typedef QPtrList<Provider> ProviderList;
-
-	/**
-	 * Convenience representation for iterator for the plugin providers
-	 *
-	 * You would use this something like the following:
-	 * \code
-	 * QCA::ProviderList qcaProviders = QCA::providers();
-	 * QCA::ProviderListIterator it( qcaProviders );
-	 * QCA::Provider *provider;
-	 * while ( 0 != (provider = it.current() ) ) {
-	 *     ++it;
-	 *     cout << provider->name();
-	 * }
-	 * \endcode
-	 *
-	 * \sa ProviderList
-	 * \sa providers()
-	 */
-	typedef QPtrListIterator<Provider> ProviderListIterator;
-
-	/**
-	 * Mode settings for memory allocation
-	 *
-	 * QCA can use secure memory, however most operating systems
-	 * restrict the amount of memory that can be pinned by user
-	 * applications, to prevent a denial-of-service attack. 
-	 *
-	 * QCA supports two approaches to getting memory - the mlock
-	 * method, which generally requires root (administrator) level
-	 * privileges, and the mmap method which is not as secure, but
-	 * which should be able to be used by any process.
-	 * 
-	 * \sa Initializer
-	 */
-	enum MemoryMode
-	{
-		Practical, ///< mlock and drop root if available, else mmap
-		Locking, ///< mlock and drop root
-		LockingKeepPrivileges ///< mlock, retaining root privileges
-	};
-
-	/**
-	 * Direction settings for symmetric algorithms
-	 *
-	 * For some algorithms, it makes sense to have a "direction", such
-	 * as Cipher algorithms which can be used to encrypt or decrypt.
-	 */
-	enum Direction
-	{
-		Encode, ///< Operate in the "forward" direction; for example, encrypting
-		Decode  ///< Operate in the "reverse" direction; for example, decrypting
-	};
-
-	enum DL_Group
-	{
-		DSA_512,
-		DSA_768,
-		DSA_1024,
-		IETF_768,
-		IETF_1024,
-		IETF_1536,
-		IETF_2048,
-		IETF_3072,
-		IETF_4096
-	};
-
-	enum EncAlgo
-	{
-		EME_PKCS1v15,
-		EME_PKCS1_OAEP
-	};
-
-	enum SignAlgo
-	{
-		SignUnknown,
-		EMSA1_SHA1, // usual dsa
-		EMSA3_SHA1,
-		EMSA3_MD5, // usual rsa
-		EMSA3_MD2,
-		EMSA3_RIPEMD160
-	};
-
-	enum CertValidity
-	{
-		Valid,
-		Rejected,
-		Untrusted,
-		SignatureFailed,
-		InvalidCA,
-		InvalidPurpose,
-		SelfSigned,
-		Revoked,
-		PathLengthExceeded,
-		Expired,
-		Unknown
-	};
-
-	enum CertUsage
-	{
-		Any             = 0x00,
-		TLSServer       = 0x01,
-		TLSClient       = 0x02,
-		CodeSigning     = 0x04,
-		EmailProtection = 0x08,
-		TimeStamping    = 0x10,
-		CRLSigning      = 0x20
-	};
-
-	/**
-	 * Specify the lower-bound for acceptable TLS/SASL security layers
-	 */
-	enum SecurityLevel
-	{
-		SL_None,      ///< indicates that no security is ok
-		SL_Integrity, ///< must at least get integrity protection
-		SL_Export,    ///< must be export level bits or more
-		SL_Baseline,  ///< must be 128 bit or more
-		SL_High,      ///< must be more than 128 bit
-		SL_Highest    ///< SL_High or max possible, whichever is greater
-	};
-
-	/**
-	 * Initialise %QCA.
-	 * This call is not normally required, because it is cleaner
-	 * to use an Initializer.
-	 */
-	QCA_EXPORT void init();
-
-	/**
-	 * \overload
-	 *
-	 * \param m the MemoryMode to use
-	 * \param prealloc the amount of memory in kilobytes to allocate
-	 *                 for secure storage
-	 */
-	QCA_EXPORT void init(MemoryMode m, int prealloc);
-
-	/**
-	 * Clean up routine
-	 *
-	 * This routine cleans up %QCA, including memory allocations
-	 * This call is not normally required, because it is cleaner
-	 * to use an Initializer
-	 */
-	QCA_EXPORT void deinit();
-
-	/**
-	 * Test if secure storage memory is available
-	 *
-	 * \return true if secure storage memory is available
-	 */ 
-	QCA_EXPORT bool haveSecureMemory();
-
-	/**
-	 * Test if a capability (algorithm) is available.
-	 *
-	 * Since capabilities are made available at runtime, you
-	 * should always check before using a capability the first
-	 * time, as shown below.
-	 * \code
-	 * QCA::init();
-         * if(!QCA::isSupported("sha1"))
-         *     printf("SHA1 not supported!\n");
-	 * else {
-         *     QString result = QCA::SHA1::hashToString(myString);
-         *     printf("sha1(\"%s\") = [%s]\n", myString.data(), result.latin1());
-	 * }
-	 * \endcode
-	 * 
-	 * \param features the name of the capability to test for
-	 *
-	 * \return true if the capability is available, otherwise false
-	 *
-	 * Note that you can test for a combination of capabilities,
-	 * using a comma delimited list:
-	 * \code
-	 * QCA::isSupported("sha1,md5"):
-	 * \endcode
-	 * which will return true if all of the capabilities listed
-	 * are present.
-	 *
-	 */
-	QCA_EXPORT bool isSupported(const char *features);
-
-	/**
-	 * \overload
-	 *
-	 * \param features a list of features to test for
-	 */
-	QCA_EXPORT bool isSupported(const QStringList &features);
-
-	/**
-	 * Generate a list of all the supported features in plugins,
-	 * and in built in capabilities
-	 *
-	 * \return a list containing the names of the features
-	 *
-	 * The following code writes a list of features to standard out
-	 * \code 
-	 * QStringList capabilities;
-	 * capabilities = QCA::supportedFeatures();
-	 * std::cout << "Supported:" << capabilities.join(",") << std::endl;
-	 * \endcode
-	 *
-	 * \sa isSupported(const char *features)
-	 * \sa isSupported(const QStringList &features)
-	 * \sa defaultFeatures()
-	 */
-	QCA_EXPORT QStringList supportedFeatures();
-
-	/**
-	 * Generate a list of the built in features. This differs from
-	 * supportedFeatures() in that it does not include features provided
-	 * by plugins.
-	 *
-	 * \return a list containing the names of the features
-	 *
-	 * The following code writes a list of features to standard out
-	 * \code 
-	 * QStringList capabilities;
-	 * capabilities = QCA::defaultFeatures();
-	 * std::cout << "Default:" << capabilities.join(",") << std::endl;
-	 * \endcode
-	 *
-	 * \sa isSupported(const char *features)
-	 * \sa isSupported(const QStringList &features)
-	 * \sa supportedFeatures()
-	 */
-	QCA_EXPORT QStringList defaultFeatures();
-
-	/**
-	 * Add a provider to the current list of providers
-	 * 
-	 * This function allows you to add a provider to the 
-	 * current plugin providers at a specified priority. If
-	 * a provider with the name already exists, this call fails.
-	 *
-	 * \param p a pointer to a Provider object, which must be
-	 *        set up.
-	 * \param priority the priority level to set the provider to
-	 *
-	 * \return true if the provider is added, and false if the 
-	 *         provider is not added (failure)
-	 *
-	 * \sa setProviderPriority for a description of the provider priority system
-	 */
-	QCA_EXPORT bool insertProvider(Provider *p, int priority = 0);
-
-	/**
-	 * Change the priority of a specified provider
-	 *
-	 * QCA supports a number of providers, and if a number of providers
-	 * support the same algorithm, it needs to choose between them. You
-	 * can do this at object instantiation time (by specifying the name
-	 * of the provider that should be used). Alternatively, you can provide a
-	 * relative priority level at an application level, using this call.
-	 * 
-	 * Priority is used at object instantiation time. The provider is selected
-	 * according to the following logic:
-	 * - if a particular provider is nominated, and that provider supports
-	 *   the required algorithm, then the nominated provider is used
-	 * - if no provider is nominated, or it doesn't support the required
-	 *   algorithm, then the provider with the lowest priority number will be used,
-	 *   if that provider supports the algorithm.
-	 * - if the provider with the lowest priority number doesn't support 
-	 *   the required algorithm, the provider with the next lowest priority number
-	 *   will be tried,and so on through to the provider with the largest priority number
-	 * - if none of the plugin providers support the required algorithm, then
-	 *   the default (built-in) provider will be tried.
-	 * 
-	 * \param name the name of the provider
-	 * \param priority the new priority of the provider. As a special case, if
-	 *        you pass in -1, then this provider gets the same priority as the
-	 *        the last provider that was added or had its priority set using this
-	 *        call.
-	 *
-	 * \sa providerPriority
-	 */
-	QCA_EXPORT void setProviderPriority(const QString &name, int priority);
-
-	/**
-	 * Return the priority of a specified provider
-	 *
-	 * The name of the provider (eg "qca-openssl") is used to look up the 
-	 * current priority associated with that provider. If the provider
-	 * is not found (or something else went wrong), -1 is returned.
-	 *
-	 * \param name the name of the provider
-	 *
-	 * \return the current priority level
-	 *
-	 * \sa setProviderPriority for a description of the provider priority system
-	 */
-	QCA_EXPORT int providerPriority(const QString &name);
-
-	/**
-	 * Return a list of the current providers
-	 *
-	 * The current plugin providers are provided as a list, which you
-	 * can iterate over using ProviderListIterator.
-	 *
-	 * \sa ProviderList
-	 * \sa ProviderListIterator
-	 */
-	QCA_EXPORT const ProviderList & providers();
-
-	/**
-	 * Unload the current plugins
-	 *
-	 */
-	QCA_EXPORT void unloadAllPlugins();
-
-	/**
-	 * Return the Random provider that is currently set to be the
-	 * global random number generator.
-	 *
-	 * For example, to get the name of the provider that is currently
-	 * providing the Random capability, you could use:
-	 * \code
-	 * QCA::Random rng = QCA::globalRNG();
-         * std::cout << "Provider name: " << rng.provider()->name() << std::endl;
-	 * \endcode
-	 */
-	QCA_EXPORT Random & globalRNG();
-
-	/**
-	 * Change the global random generation provider
-	 *
-	 * The Random capabilities of %QCA are provided as part of the
-	 * built in capabilities, however the generator can be changed
-	 * if required.
-	 */
-	QCA_EXPORT void setGlobalRNG(const QString &provider);
-
-	QCA_EXPORT bool haveSystemStore();
-	QCA_EXPORT Store systemStore(const QString &provider = QString() );
-
-	/**
-	 * Get the application name that will be used by SASL server mode
-	 *
-	 * The application name is used by SASL in server mode, as some systems might
-	 * have different security policies depending on the app.
-	 * The default application name  is 'qca'
-	 */
-	QCA_EXPORT QString appName();
-
-	/**
-	 * Set the application name that will be used by SASL server mode
-	 *
-	 * The application name is used by SASL in server mode, as some systems might
-	 * have different security policies depending on the app. This should be set 
-	 * before using SASL objects, and it cannot be changed later.
-	 *
-	 * \param name the name string to use for SASL server mode
-	 */
-	QCA_EXPORT void setAppName(const QString &name);
-
-	/**
-	 * Convert a byte array to printable hexadecimal
-	 * representation.
-	 *
-	 * This is a convenience function to convert an arbitrary
-	 * QSecureArray to a printable representation.
-	 *
-	 * \code
-	 * 	QSecureArray test(10);
-	 *	test.fill('a');
-	 * 	// 0x61 is 'a' in ASCII
-	 *	if (QString("61616161616161616161") == QCA::arrayToHex(test) ) {
-	 *		printf ("arrayToHex passed\n");
-	 *	}
-	 * \endcode
-	 *
-	 * \param array the array to be converted
-	 * \return a printable representation
-	 */
-	QCA_EXPORT QString arrayToHex(const QSecureArray &array);
-
-	/**
-	 * Convert a QString containing a hexadecimal representation
-	 * of a byte array into a QByteArray
-	 *
-	 * This is a convenience function to convert a printable
-	 * representation into a QByteArray - effectively the inverse
-	 * of QCA::arrayToHex.
-	 *
-	 * \code
-	 * 	QCA::init();
-	 * 	QByteArray test(10);
-	 *
-	 *	test.fill('b'); // 0x62 in hexadecimal
-	 *	test[7] = 0x00; // can handle strings with nulls
-	 *
-	 *	if (QCA::hexToArray(QString("62626262626262006262") ) == test ) {
-	 *		printf ("hexToArray passed\n");
-	 *	}
-	 * \endcode
-	 *
-	 * \param hexString the string containing a printable
-	 * representation to be converted
-	 * \return the equivalent QByteArray
-	 *
-	 */
-	QCA_EXPORT QByteArray hexToArray(const QString &hexString);
-
-	/**
-	 * Convenience method for initialising and cleaning up %QCA
-	 *
-	 * To ensure that QCA is properly initialised and cleaned up,
-	 * it is convenient to create an Initializer object, and let it
-	 * go out of scope at the end of %QCA usage.
-	 */
-	class QCA_EXPORT Initializer
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * \param m the MemoryMode to use for secure memory
-		 * \param prealloc the amount of secure memory to pre-allocate,
-		 *        in units of 1024 bytes (1K).
-		 */
-		Initializer(MemoryMode m = Practical, int prealloc = 64);
-		~Initializer();
-	};
-
-	/**
-	 * Simple container for acceptable key lengths
-	 *
-	 * The KeyLength specifies the minimum and maximum byte sizes
-	 * allowed for a key, as well as a "multiple" which the key
-	 * size must evenly divide into.
-	 * 
-	 * As an example, if the key can be 4, 8 or 12 bytes, you can
-	 * express this as 
-	 * \code
-	 * KeyLength keyLen( 4, 12, 4 );
-	 * \endcode
-	 * 
-	 * If you want to express a KeyLength that takes any number
-	 * of bytes (including zero), you may want to use
-	 * \code
-	 * #include<limits>
-	 * KeyLength( 0, std::numeric_limits<int>::max(), 1 );
-	 * \endcode
-	 */
-	class QCA_EXPORT KeyLength
-	{
-	public:
-		/**
-		 * Construct a %KeyLength object
-		 *
-		 * \param min the minimum length of the key, in bytes
-		 * \param max the maximum length of the key, in bytes
-		 * \param multiple the number of bytes that the key must be a 
-		 * multiple of.
-		 */
-		KeyLength(int min, int max, int multiple)
-			: _min( min ), _max(max), _multiple( multiple )
-		{ }
-		/**
-		 * Obtain the minimum length for the key, in bytes
-		 */
-		int minimum() const { return _min; }
-
-		/**
-		 * Obtain the maximum length for the key, in bytes
-		 */
-		int maximum() const { return _max; }
-
-		/**
-		 * Return the number of bytes that the key must be a multiple of
-		 *
-		 * If this is one, then anything between minumum and maximum (inclusive)
-		 * is acceptable.
-		 */
-		int multiple() const { return _multiple; }
-
-	private:
-		int const _min, _max, _multiple;
-	};
-
-	/**
-	 * Algorithm provider
-	 *
-	 * %Provider represents a plugin provider (or as a special case, the
-	 * built-in provider). This is the class you need to inherit
-	 * from to create your own plugin. You don't normally need to 
-	 * worry about this class if you are just using existing 
-	 * QCA capabilities and plugins, however there is nothing stopping
-	 * you from using it to obtain information about specific plugins,
-	 * as shown in the example below.
-	 */
-	class QCA_EXPORT Provider
-	{
-	public:
-		virtual ~Provider();
-
-		class Context
-		{
-		public:
-			Context(Provider *parent, const QString &type);
-			virtual ~Context();
-
-			Provider *provider() const;
-			QString type() const;
-			virtual Context *clone() const = 0;
-			bool sameProvider(Context *c);
-
-			int refs;
-
-		private:
-			Provider *_provider;
-			QString _type;
-		};
-
-		/**
-		 * Initialisation routine.
-		 * 
-		 * This routine will be called when your plugin
-		 * is loaded, so this is a good place to do any
-		 * one-off initialisation tasks. If you don't need
-		 * any initialisation, just implement it as an empty
-		 * routine.
-		 */
-		virtual void init();
-
-		/**
-		 * The name of the provider.
-		 * 
-		 * Typically you just return a string containing a 
-		 * convenient name.
-		 *
-		 * \code
-		 * QString name() const
-		 * {
-		 *        return "qca-myplugin";
-		 * }
-		 * \endcode
-		 *
-		 * \note  The name is used to tell if a provider is
-		 * already loaded, so you need to make sure it is
-		 * unique amongst the various plugins.
-		 */
-		virtual QString name() const = 0;
-
-		/**
-		 * The capabilities (algorithms) of the provider.
-		 *
-		 * Typically you just return a fixed QStringList:
-		 * \code
-		 * QStringList features() const
-		 * {
-		 *      QStringList list;
-		 *      list += "sha1";
-		 *      list += "sha256";
-		 *      list += "hmac(md5)";
-		 *      return list;
-		 * }
-		 * \endcode
-		 */
-		virtual QStringList features() const = 0;
-
-		/**
-		 * Routine to create a plugin context
-		 *
-		 * You need to return a pointer to an algorithm
-		 * Context that corresponds with the algorithm
-		 * name specified. 
-		 *
-		 * \param type the name of the algorithm required
-		 *
-		 * \code
-		 * Context *createContext(const QString &type)
-		 * {
-		 * if ( type == "sha1" )
-		 *     return new SHA1Context( this );
-		 * else if ( type == "sha256" )
-		 *     return new SHA0256Context( this );
-		 * else if ( type == "hmac(sha1)" )
-		 *     return new HMACSHA1Context( this );
-		 * else
-		 *     return 0;
-		 * }
-		 * \endcode
-		 * 
-		 * Naturally you also need to implement
-		 * the specified Context subclasses as well.
-		 */
-		virtual Context *createContext(const QString &type) = 0;
-	};
-
-	/**
-	 General superclass for buffered computation algorithms
-
-	 A buffered computation is characterised by having the
-	 algorithm take data in an incremental way, then having
-	 the results delivered at the end. Conceptually, the
-	 algorithm has some internal state that is modified
-	 when you call update() and returned when you call
-	 final().
-	*/
-	class QCA_EXPORT BufferedComputation
-	{
-	public:
-		virtual ~BufferedComputation();
-
-		/**
-		   Reset the internal state
-		*/
-		virtual void clear() = 0;
-
-		/**
-		   Update the internal state with a byte array
-
-		   \param a the byte array of data that is to 
-		   be used to update the internal state.
-		*/
-		virtual void update(const QSecureArray &a) = 0;
-
-		/**
-		   Complete the algorithm and return the internal state
-		*/
-		virtual QSecureArray final() = 0;
-
-		/**
-		   Perform an "all in one" update, returning
-		   the result. This is appropriate if you
-		   have all the data in one array - just
-		   call process on that array, and you will
-		   get back the results of the computation.
-
-		   \note This will invalidate any previous
-		   computation using this object.
-		*/
-		QSecureArray process(const QSecureArray &a);
-	};
-
-	/**
-	 General superclass for filtering transformation algorithms
-
-	 A filtering computation is characterised by having the
-	 algorithm take input data in an incremental way, with results
-	 delivered for each input, or block of input. Some internal
-	 state may be managed, with the transformation completed
-	 when final() is called. 
-	*/
-	class QCA_EXPORT Filter
-	{
-	public:
-		virtual ~Filter();
-
-		virtual void clear() = 0;
-		virtual QSecureArray update(const QSecureArray &a) = 0;
-		virtual QSecureArray final() = 0;
-		virtual bool ok() const = 0;
-		QSecureArray process(const QSecureArray &a);
-	};
-
-	class QCA_EXPORT TextFilter : public Filter
-	{
-	public:
-		TextFilter(Direction dir);
-
-		void setup(Direction dir);
-		QSecureArray encode(const QSecureArray &a);
-		QSecureArray decode(const QSecureArray &a);
-		QString arrayToString(const QSecureArray &a);
-		QSecureArray stringToArray(const QString &s);
-		QString encodeString(const QString &s);
-		QString decodeString(const QString &s);
-
-	protected:
-		Direction _dir;
-	};
-
-	class QCA_EXPORT Hex : public TextFilter
-	{
-	public:
-		Hex(Direction dir = Encode);
-
-		virtual void clear();
-		virtual QSecureArray update(const QSecureArray &a);
-		virtual QSecureArray final();
-		virtual bool ok() const;
-
-	private:
-		uchar val;
-		bool partial;
-		bool _ok;
-	};
-
-	class QCA_EXPORT Base64 : public TextFilter
-	{
-	public:
-		Base64(Direction dir = Encode);
-
-		virtual void clear();
-		virtual QSecureArray update(const QSecureArray &a);
-		virtual QSecureArray final();
-		virtual bool ok() const;
-
-	private:
-		QSecureArray partial;
-		bool _ok;
-	};
-
-	/**
-	 General superclass for an algorithm
-	*/
-	class QCA_EXPORT Algorithm
-	{
-	public:
-		Algorithm(const Algorithm &from);
-		virtual ~Algorithm();
-
-		/**
-		   Assignment operator
-		   
-		   \param from the Algorithm to copy state from
-		*/
-		Algorithm & operator=(const Algorithm &from);
-
-		/**
-		   The type of algorithm
-		*/
-		QString type() const;
-
-		/**
-		 The name of the provider
-
-		 Each algorithm is implemented by a provider. This
-		 allows you to figure out which provider is associated
-		*/
-		Provider *provider() const;
-
-	protected:
-		Algorithm();
-		Algorithm(const QString &type, const QString &provider);
-		Provider::Context *context() const;
-		void change(Provider::Context *c);
-		void change(const QString &type, const QString &provider);
-		void detach();
-
-	private:
-		class Private;
-		Private *d;
-	};
-
-	/**
-	 * Source of random numbers
-	 *
-	 * QCA provides a built in source of random numbers, which
-	 * can be accessed through this class. You can also use
-	 * an alternative random number source, by implementing
-	 * another provider.
-	 *
-	 * You can select the "quality" of the random numbers. For 
-	 * best results, you should use Nonce or PublicValue for values
-	 * that are likely to become public, and SessionKey or LongTermKey
-	 * for those values that are more critical. All that said, please
-	 * note that this is only a hint to the provider - it may make
-	 * no difference at all.
-	 *
-	 * The normal use of this class is expected to be through the
-	 * static members - randomChar(), randomInt() and randomArray().
-	 */
-	class QCA_EXPORT Random : public Algorithm
-	{
-	public:
-		/**
-		 * How much entropy to use for the random numbers that
-		 * are required.
-		 */
-		enum Quality { Nonce, PublicValue, SessionKey, LongTermKey };
-
-		/**
-		 * Standard Constructor
-		 *
-		 * \param provider the provider library for the random
-		 *                 number generation
-		 */ 
-		Random(const QString &provider = QString() );
-
-		/**
-		 * Provide a random byte.
-		 *
-		 * This method isn't normally required - you should use
-		 * the static randomChar() method instead.
-		 * 
-		 * \param q the quality of the random byte that is required
-		 *
-		 * \sa randomChar
-		 */
-		uchar nextByte(Quality q = SessionKey);
-
-		/**
-		 * Provide a specified number of random bytes
-		 *
-		 * This method isn't normally required - you should use
-		 * the static randomArray() method instead.
-		 *
-		 * \param size the number of bytes to provide
-		 * \param q the quality of the random bytes that are required
-		 *
-		 * \sa randomArray
-		 */
-		QSecureArray nextBytes(int size, Quality q = SessionKey);
-
-		/**
-		 * Provide a random character (byte)
-		 *
-		 * This is the normal way of obtaining a single random char
-		 * (ie. 8 bit byte), of the default quality, as shown below:
-		 * \code
-		 * myRandomChar = QCA::Random::randomChar();
-		 * \endcode
-		 * 
-		 * \param q the quality of the random character that is required
-		 *
-		 * If you need a number of bytes, perhaps randomArray() may be of use
-		 */
-		static uchar randomChar(Quality q = SessionKey);
-
-		/**
-		 * Provide a random integer
-		 *
-		 * This is the normal way of obtaining a single random integer,
-		 * as shown below:
-		 * \code
-		 * // default quality
-		 * myRandomInt = QCA::Random::randomInt();
-		 * // cheap integer
-		 * myCheapInt = QCA::Random::randomInt( QCA::Random::Nonce );
-		 * \endcode
-		 *
-		 * \param q the quality of the random integer that is required
-		 */
-		static uint randomInt(Quality q = SessionKey);
-
-		/**
-		 * Provide a specified number of random bytes
-		 * 
-		 * \code
-		 * // build a 30 byte secure array.
-		 * QSecureArray arry = QCA::Random::randomArray(30);
-		 * // take 20 bytes, as high a quality as we can get
-		 * QSecureArray newKey = QCA::Random::randomArray(20, QCA::Random::LongTermKey);
-		 * \endcode
-		 *
-		 * \param size the number of bytes to provide
-		 * \param q the quality of the random bytes that are required
-		 */
-		static QSecureArray randomArray(int size, Quality q = SessionKey);
-	};
-
-	/**
-	 * Container for keys for symmetric encryption algorithms.
-	 */
-	class QCA_EXPORT SymmetricKey : public QSecureArray
-	{
-	public:
-		/**
-		 * Construct an empty (zero length) key
-		 */
-		SymmetricKey();
-
-		/**
-		 * Construct an key of specified size, with random contents
-		 *
-		 * This is intended to be used as a random session key.
-		 *
-		 * \param size the number of bytes for the key
-		 *
-		 */
-		SymmetricKey(int size);
-
-		/**
-		 * Construct a key from a provided byte array
-		 *
-		 * \param a the byte array to copy
-		 */
-		SymmetricKey(const QSecureArray &a);
-
-		/**
-		 * Construct a key from a provided string
-		 *
-		 * \param cs the QCString to copy
-		 */
-		SymmetricKey(const QCString &cs);
-
-		/**
-		 * Test for weak DES keys
-		 *
-		 * \return true if the key is a weak key for DES
-		 */
-		bool isWeakDESKey();
-	};
-
-
-	/**
-	 * Container for initialisation vectors and nonces
-	 */
-	class QCA_EXPORT InitializationVector : public QSecureArray
-	{
-	public:
-		/** 
-		 * Construct an empty (zero length) initisation vector
-		 */
-		InitializationVector();
-
-		/**
-		 * Construct an initialisation vector of the specified size
-		 *
-		 * \param size the length of the initialisation vector, in bytes
-		 */
-		InitializationVector(int size);
-
-		/**
-		 * Construct an initialisation vector from a provided byte array
-		 *
-		 * \param a the byte array to copy
-		 */
-		InitializationVector(const QSecureArray &a);
-
-		/**
-		 * Construct an initialisaton vector from a provided string
-		 *
-		 * \param cs the QCString to copy
-		 */
-		InitializationVector(const QCString &cs);
-	};
-
-	/**
-	 * General superclass for hashing algorithms.
-	 *
-	 * %Hash is a superclass for the various hashing algorithms
-	 * within %QCA. You should not need to use it directly unless you are
-	 * adding another hashing capability to %QCA - you should be
-	 * using a sub-class. SHA1 or RIPEMD160 are recommended for
-	 * new applications, although MD2, MD4, MD5 or SHA0 may be
-	 * applicable (for interoperability reasons) for some
-	 * applications. 
-	 *
-	 * To perform a hash, you create an object (of one of the
-	 * sub-classes of %Hash), call update() with the data that
-	 * needs to be hashed, and then call final(), which returns
-	 * a QByteArray of the hash result. An example (using the SHA1
-	 * hash, with 1000 updates of a 1000 byte string) is shown below:
-	 * \code
-	 *        if(!QCA::isSupported("sha1"))
-	 *                printf("SHA1 not supported!\n");
-	 *        else {
-	 *                QByteArray fillerString;
-	 *                fillerString.fill('a', 1000);
-	 *
-	 *                QCA::SHA1 shaHash;
-	 *                for (int i=0; i<1000; i++)
-	 *                        shaHash.update(fillerString);
-	 *                QByteArray hashResult = shaHash.final();
-	 *                if ( "34aa973cd4c4daa4f61eeb2bdbad27316534016f" == QCA::arrayToHex(hashResult) ) {
-	 *                        printf("big SHA1 is OK\n");
-	 *                } else {
-	 *                        printf("big SHA1 failed\n");
-	 *                }
-	 *        }
-	 * \endcode
-	 *
-	 * If you only have a simple hash requirement - a single
-	 * string that is fully available in memory at one time - 
-	 * then you may be better off with one of the convenience
-	 * methods. So, for example, instead of creating a QCA::SHA1
-	 * or QCA::MD5 object, then doing a single update() and the final()
-	 * call; you simply call QCA::SHA1().hash() or
-	 * QCA::MD5().hash() with the data that you would otherwise
-	 * have provided to the update() call.
-	 */
-	class QCA_EXPORT Hash : public Algorithm, public BufferedComputation
-	{
-	public:
-		/**
-		 * Reset a hash, dumping all previous parts of the
-		 * message.
-		 *
-		 * This method clears (or resets) the hash algorithm,
-		 * effectively undoing any previous update()
-		 * calls. You should use this call if you are re-using
-		 * a Hash sub-class object to calculate additional
-		 * hashes.
-		 */
-		virtual void clear();
-
-		/**
-		 * Update a hash, adding more of the message contents
-		 * to the digest. The whole message needs to be added
-		 * using this method before you call final(). 
-		 *
-		 * If you find yourself only calling update() once,
-		 * you may be better off using a convenience method
-		 * such as hash() or hashToString() instead.
-		 *
- 		 * \param a the byte array to add to the hash 
-		 */
-		virtual void update(const QSecureArray &a);
-
-		/**
-		 * \overload
-		 *
-		 * \param a the QByteArray to add to the hash 
-		 */
-		virtual void update(const QByteArray &a);
-
-		/**
-		 * \overload
-		 *
-		 * This method is provided to assist with code that
-		 * already exists, and is being ported to %QCA. You are
-		 * better off passing a QSecureArray (as shown above)
-		 * if you are writing new code.
-		 *
-		 * \param data pointer to a char array
-		 * \param len the length of the array. If not specified
-		 * (or specified as a negative number), the length will be
-		 * determined with strlen(), which may not be what you want
-		 * if the array contains a null (0x00) character.
-		 */
-		virtual void update(const char *data, int len = -1);
-
-		/**
-		 * \overload
-		 *
-		 * This allows you to read from a file or other
-		 * I/O device. Note that the device must be already
-		 * open for reading
-		 *
-		 * \param file an I/O device
-		 *
-		 * If you are trying to calculate the hash of
-		 * a whole file (and it isn't already open), you
-		 * might want to use code like this:
-		 * \code
-		 * QFile f( "file.dat" );
-		 * if ( f1.open( IO_ReadOnly ) ) {
-		 *     QCA::SHA1 hashObj;
-		 *     hashObj.update( f1 );
-		 *     QString output = hashObj.final() ) ),
-		 * }
-		 * \endcode
-		 */
-		virtual void update(QIODevice &file);
-
-		/**
-		 * Finalises input and returns the hash result
-		 *
-		 * After calling update() with the required data, the
-		 * hash results are finalised and produced.
-		 *
-		 * Note that it is not possible to add further data (with
-		 * update()) after calling final(), because of the way
-		 * the hashing works - null bytes are inserted to pad
-		 * the results up to a fixed size. If you want to
-		 * reuse the Hash object, you should call clear() and
-		 * start to update() again.
-		 */
-		virtual QSecureArray final();
-
-		/**
-		 * %Hash a byte array, returning it as another
-		 * byte array.
-		 * 
-		 * This is a convenience method that returns the
-		 * hash of a QSecureArray.
-		 * 
-		 * \code
-		 * QSecureArray sampleArray(3);
-		 * sampleArray.fill('a');
-		 * QSecureArray outputArray = QCA::MD2::hash(sampleArray);
-		 * \endcode
-		 * 
-		 * \param array the QByteArray to hash
-		 *
-		 * If you need more flexibility (e.g. you are constructing
-		 * a large byte array object just to pass it to hash(), then
-		 * consider creating an Hash sub-class object, and calling
-		 * update() and final().
-		 */
-		QSecureArray hash(const QSecureArray &array);
-
-		/**
-		 * \overload
-		 *
-		 * \param cs the QCString to hash
-		 */
-		QSecureArray hash(const QCString &cs);
-
-		/**
-		 * %Hash a byte array, returning it as a printable
-		 * string
-		 * 
-		 * This is a convenience method that returns the
-		 * hash of a QSeecureArray as a hexadecimal
-		 * representation encoded in a QString.
-		 * 
-		 * \param array the QByteArray to hash
-		 *
-		 * If you need more flexibility, you can create a Hash
-		 * sub-class object, call Hash::update() as
-		 * required, then call Hash::final(), before using
-		 * the static arrayToHex() method.
-		 */
-		QString hashToString(const QSecureArray &array);
-
-		/**
-		 * \overload
-		 *
-		 * \param cs the QCString to hash		 
-		 */
-		QString hashToString(const QCString &cs);
-
-	protected:
-		/**
-		 *  Constructor to override in sub-classes.
-		 *
-		 * \param type label for the type of hash to be
-		 * implemented (eg "sha1" or "md2")
-		 * \param provider the name of the provider plugin
-		 * for the subclass (eg "qca-openssl")
-		 */
-		Hash(const QString &type, const QString &provider);
-	};
-
-        /** \page padding Padding
-
-	For those Cipher sub-classes that are block based, there are modes
-	that require a full block on encryption and decryption - %Cipher Block
-	Chaining mode and Electronic Code Book modes are good examples. 
-	
-	Since real world messages are not always a convenient multiple of a
-	block size, we have to adding <i>padding</i>. There are a number of
-	padding modes that %QCA supports, including not doing any padding
-	at all.
-	
-	If you are not going to use padding, then you can pass 
-	QCA::Cipher::NoPadding as the pad argument to the Cipher sub-class, however
-	it is then your responsibility to pass in appropriate data for
-	the mode that you are using.
-
-	The most common padding scheme is known as PKCS#7 (also PKCS#1), and
-	it specifies that the pad bytes are all equal to the length of the 
-	padding ( for example, if you need three pad bytes to complete the block, then
-	the padding is 0x03 0x03 0x03 ).
-
-	On encryption, for algorithm / mode combinations that require
-	padding, you will get a block of ciphertext when the input plain text block
-	is complete. When you call final(), you will get out the ciphertext that
-	corresponds to the last bit of plain text, plus any padding. If you had
-	provided plaintext that matched up with a block size, then the cipher
-	text block is generated from pure padding - you always get at least some
-	padding, to ensure that the padding can be safely removed on decryption.
-	
-	On decryption, for algorithm / mode combinations that use padding,
-	you will get back a block of plaintext when the input ciphertext block
-	is complete. When you call final(), you will a block that has been stripped
-	of ciphertext.
-	*/
-
-	/**
-	 * General superclass for cipher (encryption / decryption) algorithms.
-	 *
-	 * %Cipher is a superclass for the various algorithms that perform
-	 * low level encryption and decryption within %QCA. You should
-	 * not need to use it directly unless you are
-	 * adding another capability to %QCA - you should be
-	 * using a sub-class. AES is recommended for new applications.
-	 */
-	class QCA_EXPORT Cipher : public Algorithm, public Filter
-	{
-	public:
-		/**
-		 * Mode settings for cipher algorithms
-		 */
-		enum Mode
-		{
-			CBC, ///< operate in %Cipher Block Chaining mode
-			CFB, ///< operate in %Cipher FeedBack mode
-			ECB  ///< operate in Electronic Code Book mode
-		};
-
-		/**
-		 * Padding variations for cipher algorithms
-		 */
-		enum Padding
-		{
-			NoPadding, ///< Do no padding
-			PKCS7     ///< Pad using the scheme in PKCS#7
-		};
-
-		/** 
-		 * Standard copy constructor
-		 */
-		Cipher(const Cipher &from);
-		~Cipher();
-
-		Cipher & operator=(const Cipher &from);
-
-		/**
-		 * Return acceptable key lengths
-		 */
-		KeyLength keyLength() const;
-
-		/**
-		 * Test if a key length is valid for the cipher algorithm
-		 *
-		 * \param n the key length in bytes
-		 * \return true if the key would be valid for the current algorithm
-		 */
-		bool validKeyLength(int n) const;
-
-		/**
-		 * return the block size for the cipher object
-		 */
-		uint blockSize() const;
-
-		/**
-		 * reset the cipher object, to allow re-use
-		 */
-		virtual void clear();
-
-		/** 
-		 * pass in a byte array of data, which will be encrypted or decrypted
-		 * (according to the Direction that was set in the constructor or in
-		 * setup() ) and returned.
-		 *
-		 * \param a the array of data to encrypt / decrypt
-		 */
-		virtual QSecureArray update(const QSecureArray &a);
-
-		/**
-		 * complete the block of data, padding as required, and returning
-		 * the completed block
-		 */
-		virtual QSecureArray final();
-
-		virtual bool ok() const;
-
-		// note: padding only applies to CBC and ECB.  CFB ciphertext is
-		//   always the length of the plaintext.
-		void setup(Mode m, Direction dir, const SymmetricKey &key, const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7);
-
-	protected:
-		Cipher(const QString &type, Mode m, Direction dir, const SymmetricKey &key, const InitializationVector &iv, Padding pad, const QString &provider);
-	private:
-		class Private;
-		Private *d;
-	};
-
-	/**
-	 * General superclass for message authentication code (MAC) algorithms.
-	 *
-	 * %MessageAuthenticationCode is a superclass for the various 
-	 * message authentication code algorithms within %QCA. You should
-	 * not need to use it directly unless you are
-	 * adding another message authentication code capability to %QCA - you should be
-	 * using a sub-class. HMAC using SHA1 is recommended for new applications.
-	 */
-	class QCA_EXPORT MessageAuthenticationCode : public Algorithm, public BufferedComputation
-	{
-	public:
-		/**
-		 * Standard copy constructor
-		 */
-		MessageAuthenticationCode(const MessageAuthenticationCode &from);
-
-		~MessageAuthenticationCode();
-
-		/**
-		 * Assignment operator.
-		 *
-		 * Copies the state (including key) from one MessageAuthenticationCode
-		 * to another
-		 */
-		MessageAuthenticationCode & operator=(const MessageAuthenticationCode &from);
-
-		/**
-		 * Return acceptable key lengths
-		 */
-		KeyLength keyLength() const;
-
-		/**
-		 * Test if a key length is valid for the MAC algorithm
-		 *
-		 * \param n the key length in bytes
-		 * \return true if the key would be valid for the current algorithm
-		 */
-		bool validKeyLength(int n) const;
-		
-		/**
-		 * Reset a MessageAuthenticationCode, dumping all
-		 * previous parts of the message.
-		 *
-		 * This method clears (or resets) the algorithm,
-		 * effectively undoing any previous update()
-		 * calls. You should use this call if you are re-using
-		 * a %MessageAuthenticationCode sub-class object
-		 * to calculate additional MACs. Note that if the key
-		 * doesn't need to be changed, you don't need to call
-		 * setup() again, since the key can just be reused.
-		 */
-		virtual void clear();
-
-		/**
-		 * Update the MAC, adding more of the message contents
-		 * to the digest. The whole message needs to be added
-		 * using this method before you call final(). 
-		 *
-		 * \param array the message contents
-		 */
-		virtual void update(const QSecureArray &array);
-
-		/**
-		 * Finalises input and returns the MAC result
-		 *
-		 * After calling update() with the required data, the
-		 * hash results are finalised and produced.
-		 *
-		 * Note that it is not possible to add further data (with
-		 * update()) after calling final(). If you want to
-		 * reuse the %MessageAuthenticationCode object, you
-		 * should call clear() and start to update() again.
-		 */
-		virtual QSecureArray final();
-
-		/**
-		 * Initialise the MAC algorithm.
-		 *
-		 * \param key the key to use for the algorithm
-		 */
-		void setup(const SymmetricKey &key);
-
-		/**
-		 * Construct the name of the algorithm
-		 *
-		 * You can use this to build a standard name string.
-		 * You probably only need this method if you are 
-		 * creating a new subclass.
-		 */
-		static QString withAlgorithm(const QString &macType, const QString &algType);
-
-	protected:
-		/**
-		 * Special constructor for subclass initialisation
-		 *
-		 * To create HMAC with a default algorithm of "sha1", you would use something like:
-		 * \code
-		 * HMAC(const QString &hash = "sha1", const SymmetricKey &key = SymmetricKey(), const QString &provider = QString() )
-		 * : MessageAuthenticationCode(withAlgorithm("hmac", hash), key, provider)
-		 * {
-		 * }
-		 * \endcode
-		 *
-		 * \note The HMAC subclass is already provided in QCA - you don't need to create
-		 * your own.
-		 */
-		MessageAuthenticationCode(const QString &type, const SymmetricKey &key, const QString &provider);
-
-	private:
-		class Private;
-		Private *d;
-	};
-
-
-	/**
-	 * SHA-0 cryptographic message digest hash algorithm.
-	 *
-	 * %SHA0 is a 160 bit hashing function, no longer recommended
-	 * for new applications because of known (partial) attacks
-	 * against it.
-	 *
-	 * You can use this class in two basic ways - standard member
-	 * methods, and convenience methods. Both are shown in
-	 * the example below.
-	 *
-	 * \code
-	 *        if(!QCA::isSupported("sha0"))
-	 *                printf("SHA0 not supported!\n");
-	 *        else {
-	 *                QCString actualResult;
-	 *                actualResult = QCA::SHA0().hashToString(message);
-	 *
-	 *                // normal methods - update() and final()
-	 *                QByteArray fillerString;
-	 *                fillerString.fill('a', 1000);
-	 *                QCA::SHA0 shaHash;
-	 *                for (int i=0; i<1000; i++)
-	 *                        shaHash.update(fillerString);
-	 *                QByteArray hashResult = shaHash.final();
-	 *        }
-	 * \endcode
-	 *
-	 */
-	class QCA_EXPORT SHA0 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a SHA-0 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using QCA::SHA0().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the SHA0 implementation
-		 * from qca-openssl, you would use SHA0("qca-openssl")
-		 */
-		SHA0(const QString &provider = QString() ) : Hash("sha0", provider) {}
-	};
-
-	/**
-	 * SHA-1 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message (up to \f$2^{64}\f$ bits in length) and outputs a
-	 * condensed 160 bit (20 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is considered secure in that it is considered
-	 * computationally infeasible to find the message that
-	 * produced the message digest.
-	 *
-	 * You can use this class in two basic ways - standard member
-	 * methods, and convenience methods. Both are shown in
-	 * the example below.
-	 *
-	 * \code
-	 *        if(!QCA::isSupported("sha1"))
-	 *                printf("SHA1 not supported!\n");
-	 *        else {
-	 *                QCString actualResult;
-	 *                actualResult = QCA::SHA1().hashToString(message);
-	 *
-	 *                // normal methods - update() and final()
-	 *                QByteArray fillerString;
-	 *                fillerString.fill('a', 1000);
-	 *                QCA::SHA1 shaHash;
-	 *                for (int i=0; i<1000; i++)
-	 *                        shaHash.update(fillerString);
-	 *                QByteArray hashResult = shaHash.final();
-	 *        }
-	 * \endcode
-	 *
-	 * For more information, see Federal Information Processing
-	 * Standard Publication 180-2 "Specifications for the Secure
-	 * %Hash Standard", available from http://csrc.nist.gov/publications/
-	 */
-	class QCA_EXPORT SHA1 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a SHA-1 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using QCA::SHA1().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the SHA1 implementation
-		 * from qca-openssl, you would use SHA1("qca-openssl")
-		 */
-		SHA1(const QString &provider = QString() ) : Hash("sha1", provider) {}
-	};
-
-	/**
-	 * SHA-256 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message (up to \f$2^{64}\f$ bits in length) and outputs a
-	 * condensed 256 bit (32 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is considered secure in that it is considered
-	 * computationally infeasible to find the message that
-	 * produced the message digest.
-	 *
-	 * For more information, see Federal Information Processing
-	 * Standard Publication 180-2 "Specifications for the Secure
-	 * %Hash Standard", available from http://csrc.nist.gov/publications/
-	 */
-	class QCA_EXPORT SHA256 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a SHA256 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using
-		 * QCA::SHA256().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the SHA256 implementation
-		 * from qca-gcrypt, you would use SHA256("qca-gcrypt")
-		 */
-		SHA256(const QString &provider = QString() ) : Hash("sha256", provider) {}
-	};
-
-	/**
-	 * SHA-384 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message (up to \f$2^{128}\f$ bits in length) and outputs a
-	 * condensed 384 bit (48 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is considered secure in that it is considered
-	 * computationally infeasible to find the message that
-	 * produced the message digest.
-	 *
-	 * For more information, see Federal Information Processing
-	 * Standard Publication 180-2 "Specifications for the Secure
-	 * %Hash Standard", available from http://csrc.nist.gov/publications/
-	 */
-	class QCA_EXPORT SHA384 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a SHA384 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using
-		 * QCA::SHA384().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the SHA384 implementation
-		 * from qca-gcrypt, you would use SHA384("qca-gcrypt")
-		 */
-		SHA384(const QString &provider = QString() ) : Hash("sha384", provider) {}
-	};
-
-	/**
-	 * SHA-512 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message (up to \f$2^{128}\f$ bits in length) and outputs a
-	 * condensed 512 bit (64 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is considered secure in that it is considered
-	 * computationally infeasible to find the message that
-	 * produced the message digest.
-	 *
-	 * For more information, see Federal Information Processing
-	 * Standard Publication 180-2 "Specifications for the Secure
-	 * %Hash Standard", available from http://csrc.nist.gov/publications/
-	 */
-	class QCA_EXPORT SHA512 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a SHA512 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using
-		 * QCA::SHA512().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the SHA512 implementation
-		 * from qca-gcrypt, you would use SHA512("qca-gcrypt")
-		 */
-		SHA512(const QString &provider = QString() ) : Hash("sha512", provider) {}
-	};
-
-	/**
-	 * %MD2 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message and outputs a
-	 * condensed 128 bit (16 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is considered slightly more secure than MD5,
-	 * but is more expensive to compute. Unless backward
-	 * compatibility or interoperability are considerations, you
-	 * are better off using the SHA1 or RIPEMD160 hashing algorithms.
-	 *
-	 * For more information, see B. Kalinski RFC1319 "The %MD2
-	 * Message-Digest Algorithm".
-	 */
-	class QCA_EXPORT MD2 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating an MD-2 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using QCA::MD2().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the MD2 implementation
-		 * from qca-openssl, you would use MD2("qca-openssl")
-		 */
-		MD2(const QString &provider = QString() ) : Hash("md2", provider) {}
-	};
-
-	/**
-	 * %MD4 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message and outputs a
-	 * condensed 128 bit (16 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is not considered to be secure, based on
-	 * known attacks. It should only be used for
-	 * applications where collision attacks are not a
-	 * consideration (for example, as used in the rsync algorithm
-	 * for fingerprinting blocks of data). If a secure hash is
-	 * required, you are better off using the SHA1 or RIPEMD160
-	 * hashing algorithms. MD2 and MD5 are both stronger 128 bit
-	 * hashes.
-	 *
-	 * For more information, see R. Rivest RFC1320 "The %MD4
-	 * Message-Digest Algorithm".
-	 */
-	class QCA_EXPORT MD4 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating an MD-4 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using QCA::MD4().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the MD4 implementation
-		 * from qca-openssl, you would use MD4("qca-openssl")
-		 */
-		MD4(const QString &provider = QString() ) : Hash("md4", provider) {}
-	};
-
-	/**
-	 * %MD5 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message and outputs a
-	 * condensed 128 bit (16 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is not considered to be secure, based on
-	 * known attacks. It should only be used for
-	 * applications where collision attacks are not a
-	 * consideration. If a secure hash is
-	 * required, you are better off using the SHA1 or RIPEMD160
-	 * hashing algorithms.
-	 *
-	 * For more information, see R. Rivest RFC1321 "The %MD5
-	 * Message-Digest Algorithm".
-	 */
-	class QCA_EXPORT MD5 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating an MD-5 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using QCA::MD5().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the MD5 implementation
-		 * from qca-openssl, you would use MD5("qca-openssl")
-		 */
-		MD5(const QString &provider = QString() ) : Hash("md5", provider) {}
-	};
-
-	/**
-	 * %RIPEMD160 cryptographic message digest hash algorithm.
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message (up to \f$2^{64}\f$ bits in length) and outputs a
-	 * condensed 160 bit (20 byte) representation of that data
-	 * stream, known as the message digest.
-	 *
-	 * This algorithm is considered secure in that it is considered
-	 * computationally infeasible to find the message that
-	 * produced the message digest.
-	 *
-	 * You can use this class in two basic ways - standard member
-	 * methods, and convenience methods. Both are shown in
-	 * the example below.
-	 *
-	 * \code
-	 *        if(!QCA::isSupported("ripemd160")
-	 *                printf("RIPEMD-160 not supported!\n");
-	 *        else {
-	 *                QCString actualResult;
-	 *                actualResult = QCA::RIPEMD160().hashToString(message);
-	 *
-	 *                // normal methods - update() and final()
-	 *                QByteArray fillerString;
-	 *                fillerString.fill('a', 1000);
-	 *                QCA::RIPEMD160 ripemdHash;
-	 *                for (int i=0; i<1000; i++)
-	 *                        ripemdHash.update(fillerString);
-	 *                QByteArray hashResult = ripemdHash.final();
-	 *        }
-	 * \endcode
-	 *
-	 */
-	class QCA_EXPORT RIPEMD160 : public Hash
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a RIPEMD160 hash,
-		 * although if you have the whole message in memory at
-		 * one time, you may be better off using
-		 * QCA::RIPEMD160().hash()
-		 *
-		 * \param provider specify a particular provider 
-		 * to use. For example if you wanted the RIPEMD160
-		 * implementation from qca-openssl, you would use 
-		 * RIPEMD160("qca-openssl")
-		 */
-		RIPEMD160(const QString &provider = QString() ) : Hash("ripemd160", provider) {}
-	};
-
-	/**
-	 * Bruce Schneier's Blowfish %Cipher
-	 *
-	 */
-	class QCA_EXPORT BlowFish : public Cipher
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a %BlowFish encryption or decryption object.
-		 *
-		 * \param m the Mode to operate in
-		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
-		 * \param key the key to use. 
-		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
-		 *        Mode does not require padding
-		 * \param provider the provider to use (eg "qca-gcrypt" )
-		 *
-		 */
-		BlowFish(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
-		:Cipher("blowfish", m, dir, key, iv, pad, provider) {}
-	};
-
-	/**
-	 * Triple %DES %Cipher
-	 *
-	 */
-	class QCA_EXPORT TripleDES : public Cipher
-	{
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a triple %DES encryption or decryption object.
-		 *
-		 * \param m the Mode to operate in
-		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
-		 * \param key the key to use. Note that triple %DES requires a 24 byte (192 bit) key,
-		 * even though the effective key length is 168 bits.
-		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
-		 *        Mode does not require padding
-		 * \param provider the provider to use (eg "qca-gcrypt" )
-		 *
-		 */
-	public:
-		TripleDES(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
-		:Cipher("tripledes", m, dir, key, iv, pad, provider) {}
-	};
-
-	/**
-	 * %DES %Cipher
-	 *
-	 */
-	class QCA_EXPORT DES : public Cipher
-	{
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a %DES encryption or decryption object.
-		 *
-		 * \param m the Mode to operate in
-		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
-		 * \param key the key to use. Note that %DES requires a 8 byte (64 bit) key,
-		 * even though the effective key length is 56 bits.
-		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
-		 *        Mode does not require padding
-		 * \param provider the provider to use (eg "qca-gcrypt" )
-		 *
-		 */
-	public:
-		DES(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
-		:Cipher("des", m, dir, key, iv, pad, provider) {}
-	};
-
-	/**
-	 * Advanced Encryption Standard %Cipher - 128 bits
-	 *
-	 */
-	class QCA_EXPORT AES128 : public Cipher
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a 128 bit 
-		 * AES encryption or decryption object.
-		 *
-		 * \param m the Mode to operate in
-		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
-		 * \param key the key to use. Note that AES128 requires a 16 byte (128 bit) key.
-		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
-		 *        Mode does not require padding
-		 * \param provider the provider to use (eg "qca-gcrypt" )
-		 *
-		 */
-		AES128(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
-		:Cipher("aes128", m, dir, key, iv, pad, provider) {}
-	};
-
-	/**
-	 * Advanced Encryption Standard %Cipher - 192 bits
-	 *
-	 */
-	class QCA_EXPORT AES192 : public Cipher
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a 192 bit 
-		 * AES encryption or decryption object.
-		 *
-		 * \param m the Mode to operate in
-		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
-		 * \param key the key to use. Note that AES192 requires a 24 byte (192 bit) key.
-		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
-		 *        Mode does not require padding
-		 * \param provider the provider to use (eg "qca-gcrypt" )
-		 *
-		 */
-		AES192(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
-		:Cipher("aes192", m, dir, key, iv, pad, provider) {}
-	};
-
-	/**
-	 * Advanced Encryption Standard %Cipher - 256 bits
-	 *
-	 */
-	class QCA_EXPORT AES256 : public Cipher
-	{
-	public:
-		/**
-		 * Standard constructor
-		 *
-		 * This is the normal way of creating a 256 bit 
-		 * AES encryption or decryption object.
-		 *
-		 * \param m the Mode to operate in
-		 * \param dir whether this object should encrypt (QCA::Encode) or decypt (QCA::Decode)
-		 * \param key the key to use. Note that AES256 requires a 32 byte (256 bit) key.
-		 * \param iv the initialisation vector to use. Ignored for ECB mode.
-		 * \param pad the type of padding to apply (or remove, for decryption). Ignored if the 
-		 *        Mode does not require padding
-		 * \param provider the provider to use (eg "qca-gcrypt" )
-		 *
-		 */
-		AES256(Mode m = CBC, Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), const InitializationVector &iv = InitializationVector(), Padding pad = PKCS7, const QString &provider = QString() )
-		:Cipher("aes256", m, dir, key, iv, pad, provider) {}
-	};
-
-
-	/**
-	 * Keyed %Hash message authentication codes
-	 *
-	 * This algorithm takes an arbitrary data stream, known as the
-	 * message and outputs an authentication code for that message.
-	 * The authentication code is generated using a secret key in
-	 * such a way that the authentication code shows that the 
-	 * message has not be altered.
-	 *
-	 * As an example, to create a MAC using HMAC with SHA1, you
-	 * could do the following:
-	 * \code
-	 * if( QCA::isSupported( "hmac(sha1)" ) ) {
-	 *      QCA::HMAC hmacObj; // don't need to specify, "sha1" is default
-	 *	hmacObj.setup( key ); // key is a QCA::SymmetricKey, set elsewhere
-	 *                            // could also be done in constructor
-	 *    	hmacObj.update( dataArray ); // dataArray is a QSecureArray, set elsewhere
-	 *	output = hmacObj.final();
-	 * }
-	 * \endcode
-	 *
-	 * Note that if your application is potentially susceptable to "replay attacks"
-	 * where the message is sent more than once, you should include a counter in
-	 * the message that is covered by the MAC, and check that the counter is always
-	 * incremented every time you recieve a message and MAC.
-	 *
-	 * For more information, see H. Krawczyk et al. RFC2104 
-	 * "HMAC: Keyed-Hashing for Message Authentication"
-	 */
-	class QCA_EXPORT HMAC : public MessageAuthenticationCode
-	{
-	public:
-		/**
-		 * %HMAC constructor
-		 *
-		 * To create a simple HMAC object
-		 * \param hash the type of the hash (eg "sha1", "md5" or "ripemd160" )
-		 * \param key the key to use for the HMAC algorithm.
-		 * \param provider the name of the provider to use (eg "qca-openssl")
-		 *
-		 * To construct a keyed-hash message authentication code object, you
-		 * can do one of the following variations.
-		 * \code
-		 * QCA::HMAC sha1HMAC; // defaults to SHA1
-		 * QCA::HMAC sha1HMAC( "sha1" ); // explicitly SHA1, but same as above
-		 * QCA::HMAC md5HMAC( "md5" );  // MD5 algorithm
-		 * QCA::HMAC sha1HMAC( "sha1", key ); // key is a QCA::SymmetricKey
-		 * // next line uses RIPEMD160, empty key, implementation from qca-openssl provider
-		 * QCA::HMAC ripemd160HMAC( "ripemd160", QCA::SymmetricKey(), "qca-openssl" );
-		 * \endcode
-		 */
-		HMAC(const QString &hash = "sha1", const SymmetricKey &key = SymmetricKey(), const QString &provider = QString() ) : MessageAuthenticationCode(withAlgorithm("hmac", hash), key, provider) {}
-	};
-
-
-	/**
-	 * General superclass for key derivation algorithms.
-	 *
-	 * %KeyDerivationFunction is a superclass for the various 
-	 * key derivation function algorithms within %QCA. You should
-	 * not need to use it directly unless you are
-	 * adding another key derivation capability to %QCA - you should be
-	 * using a sub-class. PBKDF2 using SHA1 is recommended for new applications.
-	 */
-	class QCA_EXPORT KeyDerivationFunction : public Algorithm
-	{
-	public:
-		/**
-		 * Standard copy constructor
-		 */
-		KeyDerivationFunction(const KeyDerivationFunction &from);
-
-		~KeyDerivationFunction();
-
-		/**
-		 * Generate the key from a specified secret and salt value.
-		 * 
-		 * \note key length is ignored for some functions
-		 *
-		 * \param secret the secret (password or passphrase)
-		 * \param salt the salt to use
-		 * \param keyLength the length of key to return
-		 * \param iterationCount the number of iterations to perform
-		 *
-		 * \return the derived key
-		 */
-		SymmetricKey makeKey(const QSecureArray &secret,
-				     const InitializationVector &salt,
-				     unsigned int keyLength,
-				     unsigned int iterationCount);
-
-		/**
-		 * Construct the name of the algorithm
-		 *
-		 * You can use this to build a standard name string.
-		 * You probably only need this method if you are 
-		 * creating a new subclass.
-		 */
-		static QString withAlgorithm(const QString &kdfType, const QString &algType);
-
-	protected:
-		/**
-		 * Special constructor for subclass initialisation
- 		 */
-		KeyDerivationFunction(const QString &type, const QString &provider);
-
-	private:
-		class Private;
-		Private *d;
-	};
-
-	class QCA_EXPORT PBKDF1 : public KeyDerivationFunction
-	{
-	public:
-	    PBKDF1(const QString &algorithm = "sha1", const QString &provider = QString() ) : KeyDerivationFunction(withAlgorithm("pbkdf1", algorithm), provider) {}
-	};
-
-	class PublicKey;
-	class PrivateKey;
-	class KeyGenerator;
-	class RSAPublicKey;
-	class RSAPrivateKey;
-	class DSAPublicKey;
-	class DSAPrivateKey;
-	class DHPublicKey;
-	class DHPrivateKey;
-	class Certificate;
-	class CRL;
-	class TLS;
-
-	class QCA_EXPORT PKey : public Algorithm
-	{
-	public:
-		enum Type { RSA, DSA, DH };
-
-		PKey();
-		PKey(const PKey &from);
-		~PKey();
-
-		PKey & operator=(const PKey &from);
-
-		bool isNull() const;
-		Type type() const;
-
-		bool isRSA() const;
-		bool isDSA() const;
-		bool isDH() const;
-
-		bool isPublic() const;
-		bool isPrivate() const;
-
-		bool canKeyAgree() const;
-
-		PublicKey toPublicKey() const;
-		PrivateKey toPrivateKey() const;
-
-		friend class KeyGenerator;
-
-	protected:
-		PKey(const QString &type, const QString &provider);
-		void set(const PKey &k);
-
-		RSAPublicKey toRSAPublicKey() const;
-		RSAPrivateKey toRSAPrivateKey() const;
-		DSAPublicKey toDSAPublicKey() const;
-		DSAPrivateKey toDSAPrivateKey() const;
-		DHPublicKey toDHPublicKey() const;
-		DHPrivateKey toDHPrivateKey() const;
-
-	private:
-		class Private;
-		Private *d;
-	};
-
-	class QCA_EXPORT PublicKey : public PKey
-	{
-	public:
-		PublicKey();
-		PublicKey(const PrivateKey &k);
-
-		RSAPublicKey toRSA() const;
-		DSAPublicKey toDSA() const;
-		DHPublicKey toDH() const;
-
-		bool canEncrypt() const;
-		bool canVerify() const;
-
-		// encrypt / verify
-		int maximumEncryptSize(EncAlgo alg) const;
-		QSecureArray encrypt(EncAlgo alg, const QSecureArray &a);
-		void startVerify(SignAlgo alg);
-		void update(const QSecureArray &a);
-		bool validSignature(const QSecureArray &sig);
-		bool verifyMessage(SignAlgo alg, const QSecureArray &a, const QSecureArray &sig);
-
-		// import / export
-		QSecureArray toDER() const;
-		QString toPEM() const;
-		static PublicKey fromDER(const QSecureArray &a, const QString &provider = QString() );
-		static PublicKey fromPEM(const QString &s, const QString &provider = QString() );
-
-	protected:
-		PublicKey(const QString &type, const QString &provider);
-
-	private:
-		friend class PrivateKey;
-		friend class Certificate;
-	};
-
-	class QCA_EXPORT PrivateKey : public PKey
-	{
-	public:
-		PrivateKey();
-
-		RSAPrivateKey toRSA() const;
-		DSAPrivateKey toDSA() const;
-		DHPrivateKey toDH() const;
-
-		bool canDecrypt() const;
-		bool canSign() const;
-
-		// decrypt / sign / key agreement
-		bool decrypt(EncAlgo alg, const QSecureArray &in, QSecureArray *out);
-		void startSign(SignAlgo alg);
-		void update(const QSecureArray &);
-		QSecureArray signature();
-		QSecureArray signMessage(SignAlgo alg, const QSecureArray &a);
-		SymmetricKey deriveKey(const PublicKey &theirs);
-
-		// import / export
-		QSecureArray toDER(const QString &passphrase = QString() ) const;
-		QString toPEM(const QString &passphrase = QString() ) const;
-		static PrivateKey fromDER(const QSecureArray &a, const QString &passphrase = QString(), const QString &provider = QString() );
-		static PrivateKey fromPEM(const QString &s, const QString &passphrase = QString(), const QString &provider = QString() );
-
-	protected:
-		PrivateKey(const QString &type, const QString &provider);
-
-	private:
-		friend class TLS;
-	};
-
-	class QCA_EXPORT KeyGenerator : public QObject
-	{
-		Q_OBJECT
-	public:
-		KeyGenerator(QObject *parent = 0, const char *name = 0);
-		~KeyGenerator();
-
-		bool blocking() const;
-		void setBlocking(bool b);
-		bool isBusy() const;
-
-		void generateRSA(int bits, int exp = 65537, const QString &provider = QString() );
-		void generateDSA(DL_Group group, const QString &provider = QString() );
-		void generateDH(DL_Group group, const QString &provider = QString() );
-		PrivateKey result() const;
-
-	signals:
-		void finished();
-
-	private:
-		void done();
-
-		class Private;
-		Private *d;
-	};
-
-	class QCA_EXPORT RSAPublicKey : public PublicKey
-	{
-	public:
-		RSAPublicKey();
-		RSAPublicKey(const QBigInteger &n, const QBigInteger &e, const QString &provider = QString() );
-		RSAPublicKey(const RSAPrivateKey &k);
-
-		QBigInteger n() const;
-		QBigInteger e() const;
-	};
-
-	class QCA_EXPORT RSAPrivateKey : public PrivateKey
-	{
-	public:
-		RSAPrivateKey();
-		RSAPrivateKey(const QBigInteger &p, const QBigInteger &q, const QBigInteger &d, const QBigInteger &n, const QBigInteger &e, const QString &provider = QString() );
-
-		QBigInteger p() const;
-		QBigInteger q() const;
-		QBigInteger d() const;
-		QBigInteger n() const;
-		QBigInteger e() const;
-	};
-
-	class QCA_EXPORT DSAPublicKey : public PublicKey
-	{
-	public:
-		DSAPublicKey();
-		DSAPublicKey(DL_Group group, const QBigInteger &y, const QString &provider = QString() );
-		DSAPublicKey(const DSAPrivateKey &k);
-
-		DL_Group domain() const;
-		QBigInteger y() const;
-	};
-
-	class QCA_EXPORT DSAPrivateKey : public PrivateKey
-	{
-	public:
-		DSAPrivateKey();
-		DSAPrivateKey(DL_Group group, const QBigInteger &x, const QBigInteger &y, const QString &provider = QString() );
-
-		DL_Group domain() const;
-		QBigInteger x() const;
-		QBigInteger y() const;
-	};
-
-	class QCA_EXPORT DHPublicKey : public PublicKey
-	{
-	public:
-		DHPublicKey();
-		DHPublicKey(DL_Group group, const QBigInteger &y, const QString &provider = QString() );
-		DHPublicKey(const DHPrivateKey &k);
-
-		DL_Group domain() const;
-		QBigInteger y() const;
-	};
-
-	class QCA_EXPORT DHPrivateKey : public PrivateKey
-	{
-	public:
-		DHPrivateKey();
-		DHPrivateKey(DL_Group group, const QBigInteger &x, const QBigInteger &y, const QString &provider = QString() );
-
-		DL_Group domain() const;
-		QBigInteger x() const;
-		QBigInteger y() const;
-	};
-
-	class QCA_EXPORT Certificate : public Algorithm
-	{
-	public:
-		typedef QMap<QString, QString> Info;
-
-		Certificate();
-
-		bool isNull() const;
-
-		QDateTime notValidBefore() const;
-		QDateTime notValidAfter() const;
-
-		Info subjectInfo() const;
-		Info issuerInfo() const;
-
-		QString commonName() const;
-		QBigInteger serialNumber() const;
-		PublicKey subjectPublicKey() const;
-		SignAlgo signatureAlgorithm() const;
-		bool isCA() const;
-		bool isSelfSigned() const;
-
-		// import / export
-		QSecureArray toDER() const;
-		QString toPEM() const;
-		static Certificate fromDER(const QSecureArray &a, const QString &provider = QString() );
-		static Certificate fromPEM(const QString &s, const QString &provider = QString() );
-
-		bool matchesHostname(const QString &host) const;
-
-		bool operator==(const Certificate &a) const;
-		bool operator!=(const Certificate &a) const;
-
-	private:
-		friend class Store;
-		friend class TLS;
-	};
-
-	class QCA_EXPORT CRL : public Algorithm
-	{
-	public:
-		CRL();
-
-		bool isNull() const;
-
-		int number() const;
-		QDateTime thisUpdate() const;
-		QDateTime nextUpdate() const;
-
-		// import / export
-		QSecureArray toDER() const;
-		QString toPEM() const;
-		static CRL fromDER(const QSecureArray &a, const QString &provider = QString() );
-		static CRL fromPEM(const QString &s, const QString &provider = QString() );
-
-	private:
-		friend class Store;
-	};
-
-	class QCA_EXPORT Store : public Algorithm
-	{
-	public:
-		Store(const QString &provider = QString() );
-
-		void addCertificate(const Certificate &cert, bool trusted = false);
-		void addCRL(const CRL &crl);
-		CertValidity validate(const Certificate &cert, CertUsage u = Any) const;
-
-	private:
-		friend class TLS;
-	};
-
-	// securefilter basic rule: after calling a function that might
-	//  affect something, call others to get the results.
-	//
-	// write: call readOutgoing
-	// writeIncoming: call haveClosed/haveError, read, and readOutgoing
-	// close: call haveClosed/haveError and readOutgoing
-	// haveClosed: if Closed, call readUnprocessed
-	class QCA_EXPORT SecureFilter
-	{
-	public:
-		virtual ~SecureFilter();
-
-		virtual bool isClosable() const;
-		virtual bool haveClosed() const;
-		virtual bool haveError() const = 0;
-		virtual int bytesAvailable() const = 0;
-		virtual int bytesOutgoingAvailable() const = 0;
-		virtual void close();
-
-		// plain (application side)
-		virtual void write(const QSecureArray &a) = 0;
-		virtual QSecureArray read() = 0;
-
-		// encoded (network side)
-		virtual void writeIncoming(const QByteArray &a) = 0;
-		virtual QByteArray readOutgoing(int *plainBytes = 0) = 0;
-		virtual QSecureArray readUnprocessed();
-	};
-
-	// securelayer - "nicer" interface, using signals.  subclass
-	//  should call layerUpdateBegin/End before and after write,
-	//  writeIncoming, or close.
-	class QCA_EXPORT SecureLayer : public QObject, public SecureFilter
-	{
-		Q_OBJECT
-	public:
-		SecureLayer(QObject *parent = 0, const char *name = 0);
-
-		void setStatefulOnly(bool b);
-
-	protected:
-		void layerUpdateBegin();
-		void layerUpdateEnd();
-
-	signals:
-		void readyRead();
-		void readyReadOutgoing();
-		void closed();
-		void error();
-
-	private:
-		bool _signals;
-		int _read, _readout;
-		bool _closed, _error;
-	};
-
-	class QCA_EXPORT TLS : public SecureLayer, public Algorithm
-	{
-		Q_OBJECT
-	public:
-		enum Error
-		{
-			ErrHandshake, ///< problem during the negotiation
-			ErrCrypt      ///< problem at anytime after
-		};
-		enum IdentityResult
-		{
-			Valid,        ///< identity is verified
-			HostMismatch, ///< valid cert provided, but wrong owner
-			BadCert,      ///< invalid cert
-			NoCert        ///< identity unknown
-		};
-
-		TLS(QObject *parent = 0, const char *name = 0, const QString &provider = QString() );
-		~TLS();
-
-		void reset();
-
-		void setCertificate(const Certificate &cert, const PrivateKey &key);
-		void setStore(const Store &store);
-		void setConstraints(SecurityLevel s);
-		void setConstraints(int minSSF, int maxSSF);
-
-		bool canCompress() const;
-		void setCompressionEnabled(bool b);
-
-		bool startClient(const QString &host = QString() );
-		bool startServer();
-		bool isHandshaken() const;
-		QString cipherName() const;
-		int cipherBits() const;
-		Error errorCode() const;
-
-		IdentityResult peerIdentityResult() const;
-		CertValidity peerCertificateValidity() const;
-		Certificate localCertificate() const;
-		Certificate peerCertificate() const;
-
-		// reimplemented
-		virtual bool isClosable() const;
-		virtual bool haveClosed() const;
-		virtual bool haveError() const;
-		virtual int bytesAvailable() const;
-		virtual int bytesOutgoingAvailable() const;
-		virtual void close();
-		virtual void write(const QSecureArray &a);
-		virtual QSecureArray read();
-		virtual void writeIncoming(const QByteArray &a);
-		virtual QByteArray readOutgoing(int *plainBytes = 0);
-		virtual QSecureArray readUnprocessed();
-
-	signals:
-		void handshaken();
-
-	public:
-		class Private;
-	private:
-		friend class Private;
-		Private *d;
-	};
-
-	class QCA_EXPORT SASL : public SecureLayer, public Algorithm
-	{
-		Q_OBJECT
-	public:
-		enum Error
-		{
-			ErrAuth, ///< problem during the authentication process
-			ErrCrypt ///< problem at anytime after
-		};
-		enum AuthCondition
-		{
-			NoMech,
-			BadProto,
-			BadServ,
-			BadAuth,
-			NoAuthzid,
-			TooWeak,
-			NeedEncrypt,
-			Expired,
-			Disabled,
-			NoUser,
-			RemoteUnavail
-		};
-		enum AuthFlags
-		{
-			AllowPlain             = 0x01,
-			AllowAnonymous         = 0x02,
-			RequireForwardSecrecy  = 0x04,
-			RequirePassCredentials = 0x08,
-			RequireMutualAuth      = 0x10,
-			RequireAuthzidSupport  = 0x20  // server-only
-		};
-
-		SASL(QObject *parent = 0, const char *name = 0, const QString &provider = QString() );
-		~SASL();
-
-		void reset();
-
-		// configuration
-		void setConstraints(AuthFlags f, SecurityLevel s = SL_None);
-		void setConstraints(AuthFlags f, int minSSF, int maxSSF);
-		void setLocalAddr(const QHostAddress &addr, Q_UINT16 port);
-		void setRemoteAddr(const QHostAddress &addr, Q_UINT16 port);
-		void setExternalAuthId(const QString &authid);
-		void setExternalSSF(int);
-
-		// main
-		bool startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst = true);
-		bool startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist, bool allowServerSendLast = false);
-		void putStep(const QByteArray &stepData);
-		void putServerFirstStep(const QString &mech);
-		void putServerFirstStep(const QString &mech, const QByteArray &clientInit);
-		int ssf() const;
-		Error errorCode() const;
-		AuthCondition authCondition() const;
-
-		// authentication
-		void setUsername(const QString &user);
-		void setAuthzid(const QString &auth);
-		void setPassword(const QSecureArray &pass);
-		void setRealm(const QString &realm);
-		void continueAfterParams();
-		void continueAfterAuthCheck();
-
-		// reimplemented
-		virtual bool haveError() const;
-		virtual int bytesAvailable() const;
-		virtual int bytesOutgoingAvailable() const;
-		virtual void close();
-		virtual void write(const QSecureArray &a);
-		virtual QSecureArray read();
-		virtual void writeIncoming(const QByteArray &a);
-		virtual QByteArray readOutgoing(int *plainBytes = 0);
-
-	signals:
-		void clientFirstStep(const QString &mech, const QByteArray *clientInit);
-		void nextStep(const QByteArray &stepData);
-		void needParams(bool user, bool authzid, bool pass, bool realm);
-		void authCheck(const QString &user, const QString &authzid);
-		void authenticated();
-
-	public:
-		class Private;
-	private:
-		friend class Private;
-		Private *d;
-	};
-};
-
-#endif
diff --git a/src/qca_basic.cpp b/src/qca_basic.cpp
index 659e27c8..48fd9b85 100644
--- a/src/qca_basic.cpp
+++ b/src/qca_basic.cpp
@@ -1,6 +1,7 @@
 /*
  * qca_basic.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,7 +19,7 @@
  *
  */
 
-#include "qca.h"
+#include "qca_basic.h"
 
 #include "qcaprovider.h"
 
diff --git a/src/qca_cert.cpp b/src/qca_cert.cpp
index 76263cc9..196b2fd0 100644
--- a/src/qca_cert.cpp
+++ b/src/qca_cert.cpp
@@ -1,6 +1,7 @@
 /*
  * qca_cert.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,10 +19,11 @@
  *
  */
 
-#include "qca.h"
+#include "qca_cert.h"
 
 #include <qdatetime.h>
 #include <qregexp.h>
+#include "qca_publickey.h"
 #include "qcaprovider.h"
 
 namespace QCA {
diff --git a/src/qca.cpp b/src/qca_core.cpp
similarity index 72%
rename from src/qca.cpp
rename to src/qca_core.cpp
index e73b98b1..63ec46c1 100644
--- a/src/qca.cpp
+++ b/src/qca_core.cpp
@@ -1,6 +1,7 @@
 /*
- * qca.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2003,2004  Justin Karneges
+ * qca_core.cpp - Qt Cryptographic Architecture
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,18 +19,18 @@
  *
  */
 
-#include"qca.h"
+#include "qca_core.h"
 
-#include <qptrlist.h>
-#include <qstringlist.h>
-#include <qtimer.h>
-#include <qhostaddress.h>
-#include <qguardedptr.h>
 #include <qptrdict.h>
-#include <stdlib.h>
-#include "qcaprovider.h"
+#include "qca_tools.h"
 #include "qca_plugin.h"
-#include "qca_systemstore.h"
+#include "qca_textfilter.h"
+#include "qca_cert.h"
+#include "qcaprovider.h"
+
+#ifndef QCA_NO_SYSTEMSTORE
+# include "qca_systemstore.h"
+#endif
 
 namespace QCA {
 
@@ -585,87 +586,87 @@ SymmetricKey::SymmetricKey(const QCString &cs)
 }
 
 /* from libgcrypt-1.2.0 */
-static unsigned char desWeakKeyTable[64][8] = {
-{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/
-{ 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
-{ 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },
-{ 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
-{ 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/
-{ 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
-{ 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },
-{ 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
-{ 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/
-{ 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
-{ 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },
-{ 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
-{ 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/
-{ 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
-{ 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },
-{ 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
-{ 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
-{ 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/
-{ 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
-{ 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },
-{ 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
-{ 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/
-{ 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
-{ 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },
-{ 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
-{ 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/
-{ 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
-{ 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },
-{ 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
-{ 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/
-{ 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
-{ 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },
-{ 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
-{ 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },
-{ 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/
-{ 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },
-{ 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
-{ 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },
-{ 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/
-{ 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },
-{ 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
-{ 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },
-{ 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/
-{ 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
-{ 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },
-{ 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
-{ 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/
-{ 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
-{ 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },
-{ 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
-{ 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },
-{ 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/
-{ 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },
-{ 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
-{ 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },
-{ 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/
-{ 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },
-{ 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
-{ 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },
-{ 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/
-{ 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },
-{ 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
-{ 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },
-{ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }  /*w*/
+static unsigned char desWeakKeyTable[64][8] =
+{
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/
+	{ 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
+	{ 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },
+	{ 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
+	{ 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/
+	{ 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
+	{ 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },
+	{ 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
+	{ 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/
+	{ 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
+	{ 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },
+	{ 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
+	{ 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/
+	{ 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
+	{ 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },
+	{ 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
+	{ 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
+	{ 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/
+	{ 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
+	{ 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },
+	{ 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
+	{ 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/
+	{ 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
+	{ 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },
+	{ 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
+	{ 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/
+	{ 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
+	{ 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },
+	{ 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
+	{ 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/
+	{ 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
+	{ 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },
+	{ 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
+	{ 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },
+	{ 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/
+	{ 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },
+	{ 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
+	{ 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },
+	{ 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/
+	{ 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },
+	{ 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
+	{ 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },
+	{ 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/
+	{ 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
+	{ 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },
+	{ 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
+	{ 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/
+	{ 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
+	{ 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },
+	{ 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
+	{ 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },
+	{ 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/
+	{ 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },
+	{ 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
+	{ 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },
+	{ 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/
+	{ 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },
+	{ 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
+	{ 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },
+	{ 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/
+	{ 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },
+	{ 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
+	{ 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },
+	{ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }  /*w*/
 };
 
 bool SymmetricKey::isWeakDESKey()
 {
-	if ( 8 != size() )
+	if(size() != 8)
 		return false; // dubious
 	QSecureArray workingCopy(8);
 	// clear parity bits
-	for (unsigned int i = 0; i < 8; i++) {
+	for(uint i = 0; i < 8; i++)
 		workingCopy[i] = (data()[i]) & 0xfe;
-	}
 	
-	for (int n = 0; n < 64; n++) {
-		if ( 0 == memcmp( workingCopy.data(), desWeakKeyTable[n], 8) ) {
+	for(int n = 0; n < 64; n++)
+	{
+		if(memcmp(workingCopy.data(), desWeakKeyTable[n], 8) == 0)
 			return true;
-		}
 	}
 	return false;
 }
diff --git a/src/qca_default.cpp b/src/qca_default.cpp
index ceb58b18..4fa3b740 100644
--- a/src/qca_default.cpp
+++ b/src/qca_default.cpp
@@ -1,6 +1,7 @@
 /*
  * qca_default.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,9 +19,8 @@
  *
  */
 
-#include "qca.h"
+#include "qca_core.h"
 
-#include <qconfig.h>
 #include <qdatetime.h>
 #include <qstringlist.h>
 #include <stdlib.h>
diff --git a/src/qca_plugin.h b/src/qca_plugin.h
index cc547945..192b6902 100644
--- a/src/qca_plugin.h
+++ b/src/qca_plugin.h
@@ -1,6 +1,7 @@
 /*
  * qca_plugin.h - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -25,7 +26,9 @@
 
 #include <qptrlist.h>
 #include <qstringlist.h>
-#include "qca.h"
+#include "qca_core.h"
+
+class QCAProvider;
 
 namespace QCA
 {
diff --git a/src/qca_publickey.cpp b/src/qca_publickey.cpp
index 3a14f3e9..0c1b88a6 100644
--- a/src/qca_publickey.cpp
+++ b/src/qca_publickey.cpp
@@ -1,6 +1,7 @@
 /*
  * qca_publickey.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,7 +19,7 @@
  *
  */
 
-#include "qca.h"
+#include "qca_publickey.h"
 
 #include <qptrdict.h>
 #include "qcaprovider.h"
diff --git a/src/qca_securelayer.cpp b/src/qca_securelayer.cpp
index 23dfaf63..99a24e83 100644
--- a/src/qca_securelayer.cpp
+++ b/src/qca_securelayer.cpp
@@ -1,6 +1,7 @@
 /*
  * qca_securelayer.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,11 +19,13 @@
  *
  */
 
-#include "qca.h"
+#include "qca_securelayer.h"
 
 #include <qtimer.h>
 #include <qhostaddress.h>
 #include <qguardedptr.h>
+#include "qca_publickey.h"
+#include "qca_cert.h"
 #include "qcaprovider.h"
 
 namespace QCA {
diff --git a/src/qca_systemstore.h b/src/qca_systemstore.h
index e7b2c57f..7c268481 100644
--- a/src/qca_systemstore.h
+++ b/src/qca_systemstore.h
@@ -23,7 +23,7 @@
 
 // NOTE: this API is private to QCA
 
-#include "qca.h"
+#include "qca_cert.h"
 
 namespace QCA
 {
diff --git a/src/qca_textfilter.cpp b/src/qca_textfilter.cpp
index 37856da2..5705731a 100644
--- a/src/qca_textfilter.cpp
+++ b/src/qca_textfilter.cpp
@@ -1,6 +1,7 @@
 /*
  * qca_textfilter.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,7 +19,7 @@
  *
  */
 
-#include "qca.h"
+#include "qca_textfilter.h"
 
 namespace QCA {
 
diff --git a/src/qca_tools.cpp b/src/qca_tools.cpp
index 1d0c2f1f..f7faf910 100644
--- a/src/qca_tools.cpp
+++ b/src/qca_tools.cpp
@@ -1,6 +1,7 @@
 /*
  * qca_tools.cpp - Qt Cryptographic Architecture
- * Copyright (C) 2004  Justin Karneges
+ * Copyright (C) 2003-2005  Justin Karneges <justin@affinix.com>
+ * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,7 +19,7 @@
  *
  */
 
-#include "qca.h"
+#include "qca_tools.h"
 
 #ifdef Q_OS_UNIX
 # include <stdlib.h>