mirror of
https://github.com/QuasarApp/qca.git
synced 2025-05-05 07:29:32 +00:00
3192 lines
90 KiB
C++
3192 lines
90 KiB
C++
/*
|
|
* 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
|