diff --git a/include/QtCrypto/qca_basic.h b/include/QtCrypto/qca_basic.h --- a/include/QtCrypto/qca_basic.h +++ b/include/QtCrypto/qca_basic.h @@ -45,7 +45,8 @@ #define QStringLiteral(str) QString::fromUtf8(str) #endif -namespace QCA { +namespace QCA +{ /** \defgroup UserAPI QCA user API @@ -72,91 +73,91 @@ class QCA_EXPORT Random : public Algorithm { public: - /** - Standard Constructor + /** + Standard Constructor - \param provider the name of the provider library for the random + \param provider the name of the provider library for the random number generation - */ - Random(const QString &provider = QString()); + */ + Random(const QString &provider = QString()); - /** - Copy constructor + /** + Copy constructor - \param from the %Random object to copy from + \param from the %Random object to copy from */ - Random(const Random &from); + Random(const Random &from); - ~Random(); + ~Random(); - /** - Assignment operator + /** + Assignment operator - \param from the %Random object to copy state from - */ - Random & operator=(const Random &from); + \param from the %Random object to copy state from + */ + Random &operator=(const Random &from); - /** - Provide a random byte. + /** + Provide a random byte. - This method isn't normally required - you should use - the static randomChar() method instead. + This method isn't normally required - you should use + the static randomChar() method instead. - \sa randomChar - */ - uchar nextByte(); + \sa randomChar + */ + uchar nextByte(); - /** - Provide a specified number of random bytes. + /** + Provide a specified number of random bytes. - This method isn't normally required - you should use - the static randomArray() method instead. + This method isn't normally required - you should use + the static randomArray() method instead. - \param size the number of bytes to provide + \param size the number of bytes to provide - \sa randomArray - */ - SecureArray nextBytes(int size); + \sa randomArray + */ + SecureArray nextBytes(int size); - /** - Provide a random character (byte) + /** + Provide a random character (byte) - This is the normal way of obtaining a single random char - (ie. 8 bit byte), as shown below: - \code -myRandomChar = QCA::Random::randomChar(); - \endcode + This is the normal way of obtaining a single random char + (ie. 8 bit byte), as shown below: + \code + myRandomChar = QCA::Random::randomChar(); + \endcode - If you need a number of bytes, perhaps randomArray() may be of use. - */ - static uchar randomChar(); + If you need a number of bytes, perhaps randomArray() may be of use. + */ + static uchar randomChar(); - /** - Provide a random integer. + /** + Provide a random integer. - This is the normal way of obtaining a single random integer, - as shown below: - \code -myRandomInt = QCA::Random::randomInt(); - \endcode - */ - static int randomInt(); + This is the normal way of obtaining a single random integer, + as shown below: + \code + myRandomInt = QCA::Random::randomInt(); + \endcode + */ + static int randomInt(); - /** - Provide a specified number of random bytes. + /** + Provide a specified number of random bytes. - \code -// build a 30 byte secure array. -SecureArray arry = QCA::Random::randomArray(30); - \endcode + \code + // build a 30 byte secure array. + SecureArray arry = QCA::Random::randomArray(30); + \endcode - \param size the number of bytes to provide - */ - static SecureArray randomArray(int size); + \param size the number of bytes to provide + */ + static SecureArray randomArray(int size); private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -178,24 +179,24 @@ \code if(!QCA::isSupported("sha1")) - printf("SHA1 not supported!\n"); + printf("SHA1 not supported!\n"); else { - QByteArray fillerString; - fillerString.fill('a', 1000); - - QCA::Hash shaHash("sha1"); - 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"); - } + QByteArray fillerString; + fillerString.fill('a', 1000); + + QCA::Hash shaHash("sha1"); + 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 @@ -215,174 +216,174 @@ class QCA_EXPORT Hash : public Algorithm, public BufferedComputation { public: - /** - Constructor + /** + Constructor - \param type label for the type of hash to be - created (for example, "sha1" or "md2") - \param provider the name of the provider plugin - for the subclass (eg "qca-ossl") - */ - explicit Hash(const QString &type, const QString &provider = QString()); + \param type label for the type of hash to be + created (for example, "sha1" or "md2") + \param provider the name of the provider plugin + for the subclass (eg "qca-ossl") + */ + explicit Hash(const QString &type, const QString &provider = QString()); - /** - Copy constructor + /** + Copy constructor - \param from the Hash object to copy from + \param from the Hash object to copy from */ - Hash(const Hash &from); + Hash(const Hash &from); - ~Hash(); + ~Hash(); - /** - Assignment operator + /** + Assignment operator - \param from the Hash object to copy state from + \param from the Hash object to copy state from */ - Hash & operator=(const Hash &from); - - /** - Returns a list of all of the hash types available - - \param provider the name of the provider to get a list from, if one - provider is required. If not specified, available hash types from all - providers will be returned. - */ - static QStringList supportedTypes(const QString &provider = QString()); - - /** - Return the hash type - */ - QString type() const; - - /** - 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 MemoryRegion &a); - - /** - \overload - - \param a the QByteArray to add to the hash - */ - 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 SecureArray (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. - */ - 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 ( f.open( QIODevice::ReadOnly ) ) -{ - QCA::Hash hashObj("sha1"); - hashObj.update( &f ); - QByteArray output = hashObj.final().toByteArray(); -} - \endcode - */ - 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 MemoryRegion final(); - - /** - %Hash a byte array, returning it as another - byte array - - This is a convenience method that returns the - hash of a SecureArray. - - \code -SecureArray sampleArray(3); -sampleArray.fill('a'); -SecureArray outputArray = QCA::Hash("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 object, and then calling - update() and final(). - */ - MemoryRegion hash(const MemoryRegion &array); - - /** - %Hash a byte array, returning it as a printable - string - - This is a convenience method that returns the - hash of a SecureArray as a hexadecimal - representation encoded in a QString. - - \param array the QByteArray to hash - - If you need more flexibility, you can create a Hash - object, call Hash::update() as required, then call - Hash::final(), before using the static arrayToHex() method. - */ - QString hashToString(const MemoryRegion &array); + Hash &operator=(const Hash &from); + + /** + Returns a list of all of the hash types available + + \param provider the name of the provider to get a list from, if one + provider is required. If not specified, available hash types from all + providers will be returned. + */ + static QStringList supportedTypes(const QString &provider = QString()); + + /** + Return the hash type + */ + QString type() const; + + /** + 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 MemoryRegion &a); + + /** + \overload + + \param a the QByteArray to add to the hash + */ + 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 SecureArray (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. + */ + 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 ( f.open( QIODevice::ReadOnly ) ) + { + QCA::Hash hashObj("sha1"); + hashObj.update( &f ); + QByteArray output = hashObj.final().toByteArray(); + } + \endcode + */ + 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 MemoryRegion final(); + + /** + %Hash a byte array, returning it as another + byte array + + This is a convenience method that returns the + hash of a SecureArray. + + \code + SecureArray sampleArray(3); + sampleArray.fill('a'); + SecureArray outputArray = QCA::Hash("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 object, and then calling + update() and final(). + */ + MemoryRegion hash(const MemoryRegion &array); + + /** + %Hash a byte array, returning it as a printable + string + + This is a convenience method that returns the + hash of a SecureArray as a hexadecimal + representation encoded in a QString. + + \param array the QByteArray to hash + + If you need more flexibility, you can create a Hash + object, call Hash::update() as required, then call + Hash::final(), before using the static arrayToHex() method. + */ + QString hashToString(const MemoryRegion &array); private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -507,7 +508,7 @@ stream, known as the message digest. The Whirlpool algorithm is considered secure in that it is considered computationally infeasible to find the message that produced the message - digest. For more information on Whirlpool, see + digest. For more information on Whirlpool, see http://paginas.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html or ISO/IEC 10118-3:2004. The label for Whirlpool is "whirlpool". @@ -525,13 +526,13 @@ padding modes that %QCA supports, including not doing any padding at all. - If you are not going to use padding, then you can pass + 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 + 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 ). PKCS#5 padding is a subset of PKCS#7 padding for 8 byte block sizes. For explanation, see @@ -578,237 +579,235 @@ padding, so they are always just the cipher name followed by the mode (e.g. "blowfish-cfb" or "aes192-ofb"). If you are not using padding with CBC mode (i.e. you are - ensuring block size operations yourself), just use + ensuring block size operations yourself), just use the cipher name followed by "-cbc" (e.g. "blowfish-cbc" - or "aes256-cbc"). + or "aes256-cbc"). \ingroup UserAPI */ class QCA_EXPORT Cipher : public Algorithm, public Filter { public: - /** - Mode settings for cipher algorithms. - - \note ECB is almost never what you want, unless you - are trying to implement a %Cipher variation that is not - supported by %QCA. - */ - enum Mode - { - CBC, ///< operate in %Cipher Block Chaining mode - CFB, ///< operate in %Cipher FeedBack mode - ECB, ///< operate in Electronic Code Book mode - OFB, ///< operate in Output FeedBack Mode - CTR, ///< operate in CounTer Mode - GCM, ///< operate in Galois Counter Mode - CCM ///< operate in Counter with CBC-MAC - }; - - /** - Padding variations for cipher algorithms. - - See the \ref paddingDescription description for more details on - padding schemes. - */ - enum Padding - { - DefaultPadding, ///< Default for cipher-mode - NoPadding, ///< Do not use padding - PKCS7 ///< Pad using the scheme in PKCS#7 - }; - - /** - Standard constructor - - \param type the name of the cipher specialisation to use (e.g. - "aes128") - \param mode the operating Mode to use (e.g. QCA::Cipher::CBC) - \param pad the type of Padding to use - \param dir the Direction that this Cipher should use (Encode for - encryption, Decode for decryption) - \param key the SymmetricKey array that is the key - \param iv the InitializationVector to use (not used for ECB mode) - \param provider the name of the Provider to use - - \note Padding only applies to CBC and ECB modes. CFB and OFB - ciphertext is always the length of the plaintext. - */ - Cipher(const QString &type, Mode mode, Padding pad = DefaultPadding, - Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), - const InitializationVector &iv = InitializationVector(), - const QString &provider = QString()); - - /** - Standard constructor - - \param type the name of the cipher specialisation to use (e.g. - "aes128") - \param mode the operating Mode to use (e.g. QCA::Cipher::CBC) - \param pad the type of Padding to use - \param dir the Direction that this Cipher should use (Encode for - encryption, Decode for decryption) - \param key the SymmetricKey array that is the key - \param iv the InitializationVector to use (not used for ECB mode) - \param tag the AuthTag to use (only for GCM and CCM modes) - \param provider the name of the Provider to use - - \note Padding only applies to CBC and ECB modes. CFB and OFB - ciphertext is always the length of the plaintext. - */ - Cipher(const QString &type, Mode mode, Padding pad, - Direction dir, const SymmetricKey &key, - const InitializationVector &iv, const AuthTag &tag, - const QString &provider = QString()); - - /** - Standard copy constructor - - \param from the Cipher to copy state from - */ - Cipher(const Cipher &from); - - ~Cipher(); - - /** - Assignment operator - - \param from the Cipher to copy state from - */ - Cipher & operator=(const Cipher &from); - - /** - Returns a list of all of the cipher types available - - \param provider the name of the provider to get a list from, if one - provider is required. If not specified, available cipher types from all - providers will be returned. - */ - static QStringList supportedTypes(const QString &provider = QString()); - - /** - Return the cipher type - */ - QString type() const; - - /** - Return the cipher mode - */ - Mode mode() const; - - /** - Return the cipher padding type - */ - Padding padding() const; - - /** - Return the cipher direction - */ - Direction direction() const; - - /** - 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 - */ - int blockSize() const; - - /** - return the authentication tag for the cipher object - */ - AuthTag tag() 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 MemoryRegion update(const MemoryRegion &a); - - /** - complete the block of data, padding as required, and returning - the completed block - */ - virtual MemoryRegion final(); - - /** - Test if an update() or final() call succeeded. - - \return true if the previous call succeeded - */ - virtual bool ok() const; - - /** - Reset / reconfigure the Cipher - - You can use this to re-use an existing Cipher, rather than creating - a new object with a slightly different configuration. - - \param dir the Direction that this Cipher should use (Encode for - encryption, Decode for decryption) - \param key the SymmetricKey array that is the key - \param iv the InitializationVector to use (not used for ECB Mode) - - \note You should not leave iv empty for any Mode except ECB. - */ - void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv = InitializationVector()); - - /** - Reset / reconfigure the Cipher - - You can use this to re-use an existing Cipher, rather than creating - a new object with a slightly different configuration. - - \param dir the Direction that this Cipher should use (Encode for - encryption, Decode for decryption) - \param key the SymmetricKey array that is the key - \param iv the InitializationVector to use (not used for ECB Mode) - \param tag the AuthTag to use (only for GCM and CCM modes) - - \note You should not leave iv empty for any Mode except ECB. - */ - void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag); - - /** - Construct a Cipher type string - - \param cipherType the name of the algorithm (eg AES128, DES) - \param modeType the mode to operate the cipher in (eg QCA::CBC, - QCA::CFB) - \param paddingType the padding required (eg QCA::NoPadding, - QCA::PCKS7) - */ - static QString withAlgorithms(const QString &cipherType, Mode modeType, Padding paddingType); + /** + Mode settings for cipher algorithms. + + \note ECB is almost never what you want, unless you + are trying to implement a %Cipher variation that is not + supported by %QCA. + */ + enum Mode { + CBC, ///< operate in %Cipher Block Chaining mode + CFB, ///< operate in %Cipher FeedBack mode + ECB, ///< operate in Electronic Code Book mode + OFB, ///< operate in Output FeedBack Mode + CTR, ///< operate in CounTer Mode + GCM, ///< operate in Galois Counter Mode + CCM ///< operate in Counter with CBC-MAC + }; + + /** + Padding variations for cipher algorithms. + + See the \ref paddingDescription description for more details on + padding schemes. + */ + enum Padding { + DefaultPadding, ///< Default for cipher-mode + NoPadding, ///< Do not use padding + PKCS7 ///< Pad using the scheme in PKCS#7 + }; + + /** + Standard constructor + + \param type the name of the cipher specialisation to use (e.g. + "aes128") + \param mode the operating Mode to use (e.g. QCA::Cipher::CBC) + \param pad the type of Padding to use + \param dir the Direction that this Cipher should use (Encode for + encryption, Decode for decryption) + \param key the SymmetricKey array that is the key + \param iv the InitializationVector to use (not used for ECB mode) + \param provider the name of the Provider to use + + \note Padding only applies to CBC and ECB modes. CFB and OFB + ciphertext is always the length of the plaintext. + */ + Cipher(const QString &type, Mode mode, Padding pad = DefaultPadding, + Direction dir = Encode, const SymmetricKey &key = SymmetricKey(), + const InitializationVector &iv = InitializationVector(), + const QString &provider = QString()); + + /** + Standard constructor + + \param type the name of the cipher specialisation to use (e.g. + "aes128") + \param mode the operating Mode to use (e.g. QCA::Cipher::CBC) + \param pad the type of Padding to use + \param dir the Direction that this Cipher should use (Encode for + encryption, Decode for decryption) + \param key the SymmetricKey array that is the key + \param iv the InitializationVector to use (not used for ECB mode) + \param tag the AuthTag to use (only for GCM and CCM modes) + \param provider the name of the Provider to use + + \note Padding only applies to CBC and ECB modes. CFB and OFB + ciphertext is always the length of the plaintext. + */ + Cipher(const QString &type, Mode mode, Padding pad, + Direction dir, const SymmetricKey &key, + const InitializationVector &iv, const AuthTag &tag, + const QString &provider = QString()); + + /** + Standard copy constructor + + \param from the Cipher to copy state from + */ + Cipher(const Cipher &from); + + ~Cipher(); + + /** + Assignment operator + + \param from the Cipher to copy state from + */ + Cipher &operator=(const Cipher &from); + + /** + Returns a list of all of the cipher types available + + \param provider the name of the provider to get a list from, if one + provider is required. If not specified, available cipher types from all + providers will be returned. + */ + static QStringList supportedTypes(const QString &provider = QString()); + + /** + Return the cipher type + */ + QString type() const; + + /** + Return the cipher mode + */ + Mode mode() const; + + /** + Return the cipher padding type + */ + Padding padding() const; + + /** + Return the cipher direction + */ + Direction direction() const; + + /** + 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 + */ + int blockSize() const; + + /** + return the authentication tag for the cipher object + */ + AuthTag tag() 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 MemoryRegion update(const MemoryRegion &a); + + /** + complete the block of data, padding as required, and returning + the completed block + */ + virtual MemoryRegion final(); + + /** + Test if an update() or final() call succeeded. + + \return true if the previous call succeeded + */ + virtual bool ok() const; + + /** + Reset / reconfigure the Cipher + + You can use this to re-use an existing Cipher, rather than creating + a new object with a slightly different configuration. + + \param dir the Direction that this Cipher should use (Encode for + encryption, Decode for decryption) + \param key the SymmetricKey array that is the key + \param iv the InitializationVector to use (not used for ECB Mode) + + \note You should not leave iv empty for any Mode except ECB. + */ + void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv = InitializationVector()); + + /** + Reset / reconfigure the Cipher + + You can use this to re-use an existing Cipher, rather than creating + a new object with a slightly different configuration. + + \param dir the Direction that this Cipher should use (Encode for + encryption, Decode for decryption) + \param key the SymmetricKey array that is the key + \param iv the InitializationVector to use (not used for ECB Mode) + \param tag the AuthTag to use (only for GCM and CCM modes) + + \note You should not leave iv empty for any Mode except ECB. + */ + void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag); + + /** + Construct a Cipher type string + + \param cipherType the name of the algorithm (eg AES128, DES) + \param modeType the mode to operate the cipher in (eg QCA::CBC, + QCA::CFB) + \param paddingType the padding required (eg QCA::NoPadding, + QCA::PCKS7) + */ + static QString withAlgorithms(const QString &cipherType, Mode modeType, Padding paddingType); private: - class Private; - Private *d; + class Private; + Private *d; }; /** \class MessageAuthenticationCode qca_basic.h QtCrypto General class for message authentication code (MAC) algorithms. - MessageAuthenticationCode is a class for accessing the various + MessageAuthenticationCode is a class for accessing the various message authentication code algorithms within %QCA. HMAC using SHA1 ("hmac(sha1)") or HMAC using SHA256 ("hmac(sha256)") is recommended for new applications. @@ -818,129 +817,129 @@ counter in the message that is covered by the MAC, and check that the counter is always incremented every time you receive a message and MAC. - For more information on HMAC, see H. Krawczyk et al. RFC2104 + For more information on HMAC, see H. Krawczyk et al. RFC2104 "HMAC: Keyed-Hashing for Message Authentication" \ingroup UserAPI */ class QCA_EXPORT MessageAuthenticationCode : public Algorithm, public BufferedComputation { public: - /** - Standard constructor - - \param type the name of the MAC (and algorithm, if applicable) to - use - \param key the shared key - \param provider the provider to use, if a particular provider is - required - */ - MessageAuthenticationCode(const QString &type, const SymmetricKey &key, const QString &provider = QString()); - - /** - Standard copy constructor - - Copies the state (including key) from one MessageAuthenticationCode - to another - - \param from the MessageAuthenticationCode to copy state from - */ - MessageAuthenticationCode(const MessageAuthenticationCode &from); - - ~MessageAuthenticationCode(); - - /** - Assignment operator. - - Copies the state (including key) from one MessageAuthenticationCode - to another - - \param from the MessageAuthenticationCode to assign from. - */ - MessageAuthenticationCode & operator=(const MessageAuthenticationCode &from); - - /** - Returns a list of all of the message authentication code types - available - - \param provider the name of the provider to get a list from, if one - provider is required. If not specified, available message authentication - codes types from all providers will be returned. - */ - static QStringList supportedTypes(const QString &provider = QString()); - - /** - Return the MAC type - */ - QString type() const; - - /** - 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 MemoryRegion &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 MemoryRegion final(); - - /** - Initialise the MAC algorithm - - \param key the key to use for the algorithm - */ - void setup(const SymmetricKey &key); + /** + Standard constructor + + \param type the name of the MAC (and algorithm, if applicable) to + use + \param key the shared key + \param provider the provider to use, if a particular provider is + required + */ + MessageAuthenticationCode(const QString &type, const SymmetricKey &key, const QString &provider = QString()); + + /** + Standard copy constructor + + Copies the state (including key) from one MessageAuthenticationCode + to another + + \param from the MessageAuthenticationCode to copy state from + */ + MessageAuthenticationCode(const MessageAuthenticationCode &from); + + ~MessageAuthenticationCode(); + + /** + Assignment operator. + + Copies the state (including key) from one MessageAuthenticationCode + to another + + \param from the MessageAuthenticationCode to assign from. + */ + MessageAuthenticationCode &operator=(const MessageAuthenticationCode &from); + + /** + Returns a list of all of the message authentication code types + available + + \param provider the name of the provider to get a list from, if one + provider is required. If not specified, available message authentication + codes types from all providers will be returned. + */ + static QStringList supportedTypes(const QString &provider = QString()); + + /** + Return the MAC type + */ + QString type() const; + + /** + 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 MemoryRegion &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 MemoryRegion final(); + + /** + Initialise the MAC algorithm + + \param key the key to use for the algorithm + */ + void setup(const SymmetricKey &key); private: - class Private; - Private *d; + class Private; + Private *d; }; /** \class KeyDerivationFunction qca_basic.h QtCrypto General superclass for key derivation algorithms. - %KeyDerivationFunction is a superclass for the various + %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 @@ -952,84 +951,84 @@ class QCA_EXPORT KeyDerivationFunction : public Algorithm { public: - /** - Standard copy constructor + /** + Standard copy constructor - \param from the KeyDerivationFunction to copy from - */ - KeyDerivationFunction(const KeyDerivationFunction &from); + \param from the KeyDerivationFunction to copy from + */ + KeyDerivationFunction(const KeyDerivationFunction &from); - ~KeyDerivationFunction(); + ~KeyDerivationFunction(); - /** - Assignment operator + /** + Assignment operator - Copies the state (including key) from one KeyDerivationFunction - to another + Copies the state (including key) from one KeyDerivationFunction + to another - \param from the KeyDerivationFunction to assign from - */ - KeyDerivationFunction & operator=(const KeyDerivationFunction &from); + \param from the KeyDerivationFunction to assign from + */ + KeyDerivationFunction &operator=(const KeyDerivationFunction &from); - /** - Generate the key from a specified secret and salt value + /** + Generate the key from a specified secret and salt value - \note key length is ignored for some functions + \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 + \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 SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount); + \return the derived key + */ + SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount); - /** - Generate the key from a specified secret and salt value + /** + Generate the key from a specified secret and salt value - \note key length is ignored for some functions + \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 msecInterval the maximum time to compute the key, in milliseconds - \param iterationCount a pointer to store the number of iteration done for the specified time + \param secret the secret (password or passphrase) + \param salt the salt to use + \param keyLength the length of key to return + \param msecInterval the maximum time to compute the key, in milliseconds + \param iterationCount a pointer to store the number of iteration done for the specified time - \return the derived key - */ - SymmetricKey makeKey(const SecureArray &secret, - const InitializationVector &salt, - unsigned int keyLength, - int msecInterval, - unsigned int *iterationCount); + \return the derived key + */ + SymmetricKey makeKey(const SecureArray &secret, + const InitializationVector &salt, + unsigned int keyLength, + int msecInterval, + unsigned int *iterationCount); - /** - Construct the name of the algorithm + /** + 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. + You can use this to build a standard name string. + You probably only need this method if you are + creating a new subclass. - \param kdfType the type of key derivation function - \param algType the name of the algorithm to use with the key derivation function + \param kdfType the type of key derivation function + \param algType the name of the algorithm to use with the key derivation function - \return the name of the KDF/algorithm pair - */ - static QString withAlgorithm(const QString &kdfType, const QString &algType); + \return the name of the KDF/algorithm pair + */ + static QString withAlgorithm(const QString &kdfType, const QString &algType); protected: - /** - Special constructor for subclass initialisation + /** + Special constructor for subclass initialisation - \param type the algorithm to create - \param provider the name of the provider to create the key derivation function in. - */ - KeyDerivationFunction(const QString &type, const QString &provider); + \param type the algorithm to create + \param provider the name of the provider to create the key derivation function in. + */ + KeyDerivationFunction(const QString &type, const QString &provider); private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -1045,14 +1044,14 @@ class QCA_EXPORT PBKDF1 : public KeyDerivationFunction { public: - /** - Standard constructor - - \param algorithm the name of the hashing algorithm to use - \param provider the name of the provider to use, if available - */ - explicit PBKDF1(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString()) - : KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf1"), algorithm), provider) {} + /** + Standard constructor + + \param algorithm the name of the hashing algorithm to use + \param provider the name of the provider to use, if available + */ + explicit PBKDF1(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString()) + : KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf1"), algorithm), provider) {} }; /** @@ -1068,14 +1067,14 @@ class QCA_EXPORT PBKDF2 : public KeyDerivationFunction { public: - /** - Standard constructor - - \param algorithm the name of the hashing algorithm to use - \param provider the name of the provider to use, if available - */ - explicit PBKDF2(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString()) - : KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf2"), algorithm), provider) {} + /** + Standard constructor + + \param algorithm the name of the hashing algorithm to use + \param provider the name of the provider to use, if available + */ + explicit PBKDF2(const QString &algorithm = QStringLiteral("sha1"), const QString &provider = QString()) + : KeyDerivationFunction(withAlgorithm(QStringLiteral("pbkdf2"), algorithm), provider) {} }; /** @@ -1092,47 +1091,47 @@ class QCA_EXPORT HKDF : public Algorithm { public: - /** - Standard constructor + /** + Standard constructor - \param algorithm the name of the hashing algorithm to use - \param provider the name of the provider to use, if available - */ - explicit HKDF(const QString &algorithm = QStringLiteral("sha256"), const QString &provider = QString()); + \param algorithm the name of the hashing algorithm to use + \param provider the name of the provider to use, if available + */ + explicit HKDF(const QString &algorithm = QStringLiteral("sha256"), const QString &provider = QString()); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the KeyDerivationFunction to copy from - */ - HKDF(const HKDF &from); + \param from the KeyDerivationFunction to copy from + */ + HKDF(const HKDF &from); - ~HKDF(); + ~HKDF(); - /** - Assignment operator + /** + Assignment operator - Copies the state (including key) from one HKDF - to another + Copies the state (including key) from one HKDF + to another - \param from the HKDF to assign from - */ - HKDF & operator=(const HKDF &from); + \param from the HKDF to assign from + */ + HKDF &operator=(const HKDF &from); - /** - Generate the key from a specified secret, salt value, and an additional info + /** + Generate the key from a specified secret, salt value, and an additional info - \note key length is ignored for some functions + \note key length is ignored for some functions - \param secret the secret (password or passphrase) - \param salt the salt to use - \param info the info to use - \param keyLength the length of key to return + \param secret the secret (password or passphrase) + \param salt the salt to use + \param info the info to use + \param keyLength the length of key to return - \return the derived key - */ - SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, - const InitializationVector &info, unsigned int keyLength); + \return the derived key + */ + SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, + const InitializationVector &info, unsigned int keyLength); }; } diff --git a/include/QtCrypto/qca_cert.h b/include/QtCrypto/qca_cert.h --- a/include/QtCrypto/qca_cert.h +++ b/include/QtCrypto/qca_cert.h @@ -37,7 +37,8 @@ #include "qca_core.h" #include "qca_publickey.h" -namespace QCA { +namespace QCA +{ class CertContext; class CSRContext; @@ -47,38 +48,35 @@ class CertificateCollection; class CertificateChain; - /** Certificate Request Format */ -enum CertificateRequestFormat -{ - PKCS10, ///< standard PKCS#10 format - SPKAC ///< Signed Public Key and Challenge (Netscape) format +enum CertificateRequestFormat { + PKCS10, ///< standard PKCS#10 format + SPKAC ///< Signed Public Key and Challenge (Netscape) format }; /** Known types of information stored in certificates This enumerator offers a convenient way to work with common types. */ -enum CertificateInfoTypeKnown -{ - CommonName, ///< The common name (eg person), id = "2.5.4.3" - Email, ///< Email address, id = "GeneralName.rfc822Name" - EmailLegacy, ///< PKCS#9 Email field, id = "1.2.840.113549.1.9.1" - Organization, ///< An organisation (eg company), id = "2.5.4.10" - OrganizationalUnit, ///< An part of an organisation (eg a division or branch), id = "2.5.4.11" - Locality, ///< The locality (eg city, a shire, or part of a state), id = "2.5.4.7" - IncorporationLocality, ///< The locality of incorporation (EV certificates), id = "1.3.6.1.4.1.311.60.2.1.1" - State, ///< The state within the country, id = "2.5.4.8" - IncorporationState, ///< The state of incorporation (EV certificates), id = "1.3.6.1.4.1.311.60.2.1.2" - Country, ///< The country, id = "2.5.4.6" - IncorporationCountry, ///< The country of incorporation (EV certificates), id = "1.3.6.1.4.1.311.60.2.1.3" - URI, ///< Uniform Resource Identifier, id = "GeneralName.uniformResourceIdentifier" - DNS, ///< DNS name, id = "GeneralName.dNSName" - IPAddress, ///< IP address, id = "GeneralName.iPAddress" - XMPP ///< XMPP address (see http://www.ietf.org/rfc/rfc3920.txt), id = "1.3.6.1.5.5.7.8.5" +enum CertificateInfoTypeKnown { + CommonName, ///< The common name (eg person), id = "2.5.4.3" + Email, ///< Email address, id = "GeneralName.rfc822Name" + EmailLegacy, ///< PKCS#9 Email field, id = "1.2.840.113549.1.9.1" + Organization, ///< An organisation (eg company), id = "2.5.4.10" + OrganizationalUnit, ///< An part of an organisation (eg a division or branch), id = "2.5.4.11" + Locality, ///< The locality (eg city, a shire, or part of a state), id = "2.5.4.7" + IncorporationLocality, ///< The locality of incorporation (EV certificates), id = "1.3.6.1.4.1.311.60.2.1.1" + State, ///< The state within the country, id = "2.5.4.8" + IncorporationState, ///< The state of incorporation (EV certificates), id = "1.3.6.1.4.1.311.60.2.1.2" + Country, ///< The country, id = "2.5.4.6" + IncorporationCountry, ///< The country of incorporation (EV certificates), id = "1.3.6.1.4.1.311.60.2.1.3" + URI, ///< Uniform Resource Identifier, id = "GeneralName.uniformResourceIdentifier" + DNS, ///< DNS name, id = "GeneralName.dNSName" + IPAddress, ///< IP address, id = "GeneralName.iPAddress" + XMPP ///< XMPP address (see http://www.ietf.org/rfc/rfc3920.txt), id = "1.3.6.1.5.5.7.8.5" }; /** @@ -120,120 +118,119 @@ class QCA_EXPORT CertificateInfoType { public: - /** - Section of the certificate that the information belongs in - */ - enum Section - { - DN, ///< Distinguished name (the primary name) - AlternativeName ///< Alternative name - }; - - /** - Standard constructor - */ - CertificateInfoType(); - - /** - Construct a new type - - The section will be derived by \a known. - - \param known the type as part of the CertificateInfoTypeKnown - enumerator - */ - CertificateInfoType(CertificateInfoTypeKnown known); - - /** - Construct a new type - - \param id the type as an identifier string (OID or internal) - \param section the section this type belongs in - - \sa id - */ - CertificateInfoType(const QString &id, Section section); - - /** - Standard copy constructor - - \param from the certificate information to copy from - */ - CertificateInfoType(const CertificateInfoType &from); - - ~CertificateInfoType(); - - /** - Standard assignment operator - - \param from the certificate information to assign from - */ - CertificateInfoType & operator=(const CertificateInfoType &from); - - /** - The section the type is part of - */ - Section section() const; - - /** - The type as part of the CertificateInfoTypeKnown enumerator - - This function may return a value that does not exist in the - enumerator. In that case, you may use id() to determine the - type. - */ - CertificateInfoTypeKnown known() const; - - /** - The type as an identifier string - - For types that have OIDs, this function returns an OID in string - form. For types that do not have OIDs, this function returns an - internal identifier string whose first character is not a digit - (this allows you to tell the difference between an OID and an - internal identifier). - - It is hereby stated that General Names (of the X.509 Subject - Alternative Name) shall use the internal identifier format - "GeneralName.[rfc field name]". For example, the rfc822Name - field would have the identifier "GeneralName.rfc822Name". - - Applications should not store, use, or compare against internal - identifiers unless the identifiers are explicitly documented - (e.g. GeneralName). - */ - QString id() const; - - /** - Comparison operator - - \param other the certificate information to compare with this - certificate information. - */ - bool operator<(const CertificateInfoType &other) const; - - /** - Comparison operator - - \param other the certificate information to compare with this - certificate information. - */ - bool operator==(const CertificateInfoType &other) const; - - /** - Inequality operator - - \param other the certificate information to compare with this - certificate information. - */ - inline bool operator!=(const CertificateInfoType &other) const - { - return !(*this == other); - } + /** + Section of the certificate that the information belongs in + */ + enum Section { + DN, ///< Distinguished name (the primary name) + AlternativeName ///< Alternative name + }; + + /** + Standard constructor + */ + CertificateInfoType(); + + /** + Construct a new type + + The section will be derived by \a known. + + \param known the type as part of the CertificateInfoTypeKnown + enumerator + */ + CertificateInfoType(CertificateInfoTypeKnown known); + + /** + Construct a new type + + \param id the type as an identifier string (OID or internal) + \param section the section this type belongs in + + \sa id + */ + CertificateInfoType(const QString &id, Section section); + + /** + Standard copy constructor + + \param from the certificate information to copy from + */ + CertificateInfoType(const CertificateInfoType &from); + + ~CertificateInfoType(); + + /** + Standard assignment operator + + \param from the certificate information to assign from + */ + CertificateInfoType &operator=(const CertificateInfoType &from); + + /** + The section the type is part of + */ + Section section() const; + + /** + The type as part of the CertificateInfoTypeKnown enumerator + + This function may return a value that does not exist in the + enumerator. In that case, you may use id() to determine the + type. + */ + CertificateInfoTypeKnown known() const; + + /** + The type as an identifier string + + For types that have OIDs, this function returns an OID in string + form. For types that do not have OIDs, this function returns an + internal identifier string whose first character is not a digit + (this allows you to tell the difference between an OID and an + internal identifier). + + It is hereby stated that General Names (of the X.509 Subject + Alternative Name) shall use the internal identifier format + "GeneralName.[rfc field name]". For example, the rfc822Name + field would have the identifier "GeneralName.rfc822Name". + + Applications should not store, use, or compare against internal + identifiers unless the identifiers are explicitly documented + (e.g. GeneralName). + */ + QString id() const; + + /** + Comparison operator + + \param other the certificate information to compare with this + certificate information. + */ + bool operator<(const CertificateInfoType &other) const; + + /** + Comparison operator + + \param other the certificate information to compare with this + certificate information. + */ + bool operator==(const CertificateInfoType &other) const; + + /** + Inequality operator + + \param other the certificate information to compare with this + certificate information. + */ + inline bool operator!=(const CertificateInfoType &other) const + { + return !(*this == other); + } private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** @@ -246,98 +243,96 @@ class QCA_EXPORT CertificateInfoPair { public: - /** - Standard constructor - */ - CertificateInfoPair(); + /** + Standard constructor + */ + CertificateInfoPair(); - /** - Construct a new pair + /** + Construct a new pair - \param type the type of information stored in this pair - \param value the value of the information to be stored - */ - CertificateInfoPair(const CertificateInfoType &type, const QString &value); + \param type the type of information stored in this pair + \param value the value of the information to be stored + */ + CertificateInfoPair(const CertificateInfoType &type, const QString &value); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the information pair to copy from - */ - CertificateInfoPair(const CertificateInfoPair &from); + \param from the information pair to copy from + */ + CertificateInfoPair(const CertificateInfoPair &from); - ~CertificateInfoPair(); + ~CertificateInfoPair(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the information pair to assign from - */ - CertificateInfoPair & operator=(const CertificateInfoPair &from); + \param from the information pair to assign from + */ + CertificateInfoPair &operator=(const CertificateInfoPair &from); - /** - The type of information stored in the pair - */ - CertificateInfoType type() const; + /** + The type of information stored in the pair + */ + CertificateInfoType type() const; - /** - The value of the information stored in the pair - */ - QString value() const; + /** + The value of the information stored in the pair + */ + QString value() const; - /** - Comparison operator + /** + Comparison operator - \param other the certificate information pair to compare with this - certificate information pair. - */ - bool operator==(const CertificateInfoPair &other) const; + \param other the certificate information pair to compare with this + certificate information pair. + */ + bool operator==(const CertificateInfoPair &other) const; - /** - Inequality operator + /** + Inequality operator - \param other the certificate information pair to compare with this - certificate information pair. - */ - inline bool operator!=(const CertificateInfoPair &other) const - { - return !(*this == other); - } + \param other the certificate information pair to compare with this + certificate information pair. + */ + inline bool operator!=(const CertificateInfoPair &other) const + { + return !(*this == other); + } private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; - /** Known types of certificate constraints This enumerator offers a convenient way to work with common types. */ -enum ConstraintTypeKnown -{ - // KeyUsage - DigitalSignature, ///< %Certificate can be used to create digital signatures, id = "KeyUsage.digitalSignature" - NonRepudiation, ///< %Certificate can be used for non-repudiation, id = "KeyUsage.nonRepudiation" - KeyEncipherment, ///< %Certificate can be used for encrypting / decrypting keys, id = "KeyUsage.keyEncipherment" - DataEncipherment, ///< %Certificate can be used for encrypting / decrypting data, id = "KeyUsage.dataEncipherment" - KeyAgreement, ///< %Certificate can be used for key agreement, id = "KeyUsage.keyAgreement" - KeyCertificateSign, ///< %Certificate can be used for key certificate signing, id = "KeyUsage.keyCertSign" - CRLSign, ///< %Certificate can be used to sign %Certificate Revocation Lists, id = "KeyUsage.crlSign" - EncipherOnly, ///< %Certificate can only be used for encryption, id = "KeyUsage.encipherOnly" - DecipherOnly, ///< %Certificate can only be used for decryption, id = "KeyUsage.decipherOnly" - - // ExtKeyUsage - ServerAuth, ///< %Certificate can be used for server authentication (e.g. web server), id = "1.3.6.1.5.5.7.3.1". This is an extended usage constraint. - ClientAuth, ///< %Certificate can be used for client authentication (e.g. web browser), id = "1.3.6.1.5.5.7.3.2". This is an extended usage constraint. - CodeSigning, ///< %Certificate can be used to sign code, id = "1.3.6.1.5.5.7.3.3". This is an extended usage constraint. - EmailProtection, ///< %Certificate can be used to sign / encrypt email, id = "1.3.6.1.5.5.7.3.4". This is an extended usage constraint. - IPSecEndSystem, ///< %Certificate can be used to authenticate a endpoint in IPSEC, id = "1.3.6.1.5.5.7.3.5". This is an extended usage constraint. - IPSecTunnel, ///< %Certificate can be used to authenticate a tunnel in IPSEC, id = "1.3.6.1.5.5.7.3.6". This is an extended usage constraint. - IPSecUser, ///< %Certificate can be used to authenticate a user in IPSEC, id = "1.3.6.1.5.5.7.3.7". This is an extended usage constraint. - TimeStamping, ///< %Certificate can be used to create a "time stamp" signature, id = "1.3.6.1.5.5.7.3.8". This is an extended usage constraint. - OCSPSigning ///< %Certificate can be used to sign an Online %Certificate Status Protocol (OCSP) assertion, id = "1.3.6.1.5.5.7.3.9". This is an extended usage constraint. +enum ConstraintTypeKnown { + // KeyUsage + DigitalSignature, ///< %Certificate can be used to create digital signatures, id = "KeyUsage.digitalSignature" + NonRepudiation, ///< %Certificate can be used for non-repudiation, id = "KeyUsage.nonRepudiation" + KeyEncipherment, ///< %Certificate can be used for encrypting / decrypting keys, id = "KeyUsage.keyEncipherment" + DataEncipherment, ///< %Certificate can be used for encrypting / decrypting data, id = "KeyUsage.dataEncipherment" + KeyAgreement, ///< %Certificate can be used for key agreement, id = "KeyUsage.keyAgreement" + KeyCertificateSign, ///< %Certificate can be used for key certificate signing, id = "KeyUsage.keyCertSign" + CRLSign, ///< %Certificate can be used to sign %Certificate Revocation Lists, id = "KeyUsage.crlSign" + EncipherOnly, ///< %Certificate can only be used for encryption, id = "KeyUsage.encipherOnly" + DecipherOnly, ///< %Certificate can only be used for decryption, id = "KeyUsage.decipherOnly" + + // ExtKeyUsage + ServerAuth, ///< %Certificate can be used for server authentication (e.g. web server), id = "1.3.6.1.5.5.7.3.1". This is an extended usage constraint. + ClientAuth, ///< %Certificate can be used for client authentication (e.g. web browser), id = "1.3.6.1.5.5.7.3.2". This is an extended usage constraint. + CodeSigning, ///< %Certificate can be used to sign code, id = "1.3.6.1.5.5.7.3.3". This is an extended usage constraint. + EmailProtection, ///< %Certificate can be used to sign / encrypt email, id = "1.3.6.1.5.5.7.3.4". This is an extended usage constraint. + IPSecEndSystem, ///< %Certificate can be used to authenticate a endpoint in IPSEC, id = "1.3.6.1.5.5.7.3.5". This is an extended usage constraint. + IPSecTunnel, ///< %Certificate can be used to authenticate a tunnel in IPSEC, id = "1.3.6.1.5.5.7.3.6". This is an extended usage constraint. + IPSecUser, ///< %Certificate can be used to authenticate a user in IPSEC, id = "1.3.6.1.5.5.7.3.7". This is an extended usage constraint. + TimeStamping, ///< %Certificate can be used to create a "time stamp" signature, id = "1.3.6.1.5.5.7.3.8". This is an extended usage constraint. + OCSPSigning ///< %Certificate can be used to sign an Online %Certificate Status Protocol (OCSP) assertion, id = "1.3.6.1.5.5.7.3.9". This is an extended usage constraint. }; /** @@ -356,161 +351,157 @@ class QCA_EXPORT ConstraintType { public: - /** - Section of the certificate that the constraint belongs in - */ - enum Section - { - KeyUsage, ///< Stored in the key usage section - ExtendedKeyUsage ///< Stored in the extended key usage section - }; - - /** - Standard constructor - */ - ConstraintType(); - - /** - Construct a new constraint - - The section will be derived by \a known. - - \param known the type as part of the ConstraintTypeKnown - enumerator - */ - ConstraintType(ConstraintTypeKnown known); - - /** - Construct a new constraint - - \param id the type as an identifier string (OID or internal) - \param section the section this type belongs in - - \sa id - */ - ConstraintType(const QString &id, Section section); - - /** - Standard copy constructor - - \param from the constraint type to copy from - */ - ConstraintType(const ConstraintType &from); - - ~ConstraintType(); - - /** - Standard assignment operator - - \param from the constraint type to assign from - */ - ConstraintType & operator=(const ConstraintType &from); - - /** - The section the constraint is part of - */ - Section section() const; - - /** - The type as part of the ConstraintTypeKnown enumerator - - This function may return a value that does not exist in the - enumerator. In that case, you may use id() to determine the - type. - */ - ConstraintTypeKnown known() const; - - /** - The type as an identifier string - - For types that have OIDs, this function returns an OID in string - form. For types that do not have OIDs, this function returns an - internal identifier string whose first character is not a digit - (this allows you to tell the difference between an OID and an - internal identifier). - - It is hereby stated that the KeyUsage bit fields shall use the - internal identifier format "KeyUsage.[rfc field name]". For - example, the keyEncipherment field would have the identifier - "KeyUsage.keyEncipherment". - - Applications should not store, use, or compare against internal - identifiers unless the identifiers are explicitly documented - (e.g. KeyUsage). - */ - QString id() const; - - /** - Comparison operator - - \param other the constraint type to compare with this constraint - */ - bool operator<(const ConstraintType &other) const; - - /** - Comparison operator - - \param other the constraint type to compare with this constraint - */ - bool operator==(const ConstraintType &other) const; - - /** - Inequality operator - - \param other the constraint type to compare with this constraint - */ - inline bool operator!=(const ConstraintType &other) const - { - return !(*this == other); - } + /** + Section of the certificate that the constraint belongs in + */ + enum Section { + KeyUsage, ///< Stored in the key usage section + ExtendedKeyUsage ///< Stored in the extended key usage section + }; + + /** + Standard constructor + */ + ConstraintType(); + + /** + Construct a new constraint + + The section will be derived by \a known. + + \param known the type as part of the ConstraintTypeKnown + enumerator + */ + ConstraintType(ConstraintTypeKnown known); + + /** + Construct a new constraint + + \param id the type as an identifier string (OID or internal) + \param section the section this type belongs in + + \sa id + */ + ConstraintType(const QString &id, Section section); + + /** + Standard copy constructor + + \param from the constraint type to copy from + */ + ConstraintType(const ConstraintType &from); + + ~ConstraintType(); + + /** + Standard assignment operator + + \param from the constraint type to assign from + */ + ConstraintType &operator=(const ConstraintType &from); + + /** + The section the constraint is part of + */ + Section section() const; + + /** + The type as part of the ConstraintTypeKnown enumerator + + This function may return a value that does not exist in the + enumerator. In that case, you may use id() to determine the + type. + */ + ConstraintTypeKnown known() const; + + /** + The type as an identifier string + + For types that have OIDs, this function returns an OID in string + form. For types that do not have OIDs, this function returns an + internal identifier string whose first character is not a digit + (this allows you to tell the difference between an OID and an + internal identifier). + + It is hereby stated that the KeyUsage bit fields shall use the + internal identifier format "KeyUsage.[rfc field name]". For + example, the keyEncipherment field would have the identifier + "KeyUsage.keyEncipherment". + + Applications should not store, use, or compare against internal + identifiers unless the identifiers are explicitly documented + (e.g. KeyUsage). + */ + QString id() const; + + /** + Comparison operator + + \param other the constraint type to compare with this constraint + */ + bool operator<(const ConstraintType &other) const; + + /** + Comparison operator + + \param other the constraint type to compare with this constraint + */ + bool operator==(const ConstraintType &other) const; + + /** + Inequality operator + + \param other the constraint type to compare with this constraint + */ + inline bool operator!=(const ConstraintType &other) const + { + return !(*this == other); + } private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** Specify the intended usage of a certificate */ -enum UsageMode -{ - UsageAny = 0x00, ///< Any application, or unspecified - UsageTLSServer = 0x01, ///< server side of a TLS or SSL connection - UsageTLSClient = 0x02, ///< client side of a TLS or SSL connection - UsageCodeSigning = 0x04, ///< code signing certificate - UsageEmailProtection = 0x08, ///< email (S/MIME) certificate - UsageTimeStamping = 0x10, ///< time stamping certificate - UsageCRLSigning = 0x20 ///< certificate revocation list signing certificate +enum UsageMode { + UsageAny = 0x00, ///< Any application, or unspecified + UsageTLSServer = 0x01, ///< server side of a TLS or SSL connection + UsageTLSClient = 0x02, ///< client side of a TLS or SSL connection + UsageCodeSigning = 0x04, ///< code signing certificate + UsageEmailProtection = 0x08, ///< email (S/MIME) certificate + UsageTimeStamping = 0x10, ///< time stamping certificate + UsageCRLSigning = 0x20 ///< certificate revocation list signing certificate }; /** The validity (or otherwise) of a certificate */ -enum Validity -{ - ValidityGood, ///< The certificate is valid - ErrorRejected, ///< The root CA rejected the certificate purpose - ErrorUntrusted, ///< The certificate is not trusted - ErrorSignatureFailed, ///< The signature does not match - ErrorInvalidCA, ///< The Certificate Authority is invalid - ErrorInvalidPurpose, ///< The purpose does not match the intended usage - ErrorSelfSigned, ///< The certificate is self-signed, and is not found in the list of trusted certificates - ErrorRevoked, ///< The certificate has been revoked - ErrorPathLengthExceeded, ///< The path length from the root CA to this certificate is too long - ErrorExpired, ///< The certificate has expired, or is not yet valid (e.g. current time is earlier than notBefore time) - ErrorExpiredCA, ///< The Certificate Authority has expired - ErrorValidityUnknown = 64 ///< Validity is unknown +enum Validity { + ValidityGood, ///< The certificate is valid + ErrorRejected, ///< The root CA rejected the certificate purpose + ErrorUntrusted, ///< The certificate is not trusted + ErrorSignatureFailed, ///< The signature does not match + ErrorInvalidCA, ///< The Certificate Authority is invalid + ErrorInvalidPurpose, ///< The purpose does not match the intended usage + ErrorSelfSigned, ///< The certificate is self-signed, and is not found in the list of trusted certificates + ErrorRevoked, ///< The certificate has been revoked + ErrorPathLengthExceeded, ///< The path length from the root CA to this certificate is too long + ErrorExpired, ///< The certificate has expired, or is not yet valid (e.g. current time is earlier than notBefore time) + ErrorExpiredCA, ///< The Certificate Authority has expired + ErrorValidityUnknown = 64 ///< Validity is unknown }; /** The conditions to validate for a certificate */ -enum ValidateFlags -{ - ValidateAll = 0x00, // Verify all conditions - ValidateRevoked = 0x01, // Verify the certificate was not revoked - ValidateExpired = 0x02, // Verify the certificate has not expired - ValidatePolicy = 0x04 // Verify the certificate can be used for a specified purpose +enum ValidateFlags { + ValidateAll = 0x00, // Verify all conditions + ValidateRevoked = 0x01, // Verify the certificate was not revoked + ValidateExpired = 0x02, // Verify the certificate has not expired + ValidatePolicy = 0x04 // Verify the certificate can be used for a specified purpose }; /** @@ -539,16 +530,16 @@ class CertificateInfoOrdered : public QList { public: - /** - Convert to RFC 1779 string format - */ - inline QString toString() const; - - /** - Return a new CertificateInfoOrdered that only contains - the Distinguished Name (DN) types found in this object. - */ - inline CertificateInfoOrdered dnOnly() const; + /** + Convert to RFC 1779 string format + */ + inline QString toString() const; + + /** + Return a new CertificateInfoOrdered that only contains + the Distinguished Name (DN) types found in this object. + */ + inline CertificateInfoOrdered dnOnly() const; }; /** @@ -568,12 +559,12 @@ inline QString CertificateInfoOrdered::toString() const { - return orderedToDNString(*this); + return orderedToDNString(*this); } inline CertificateInfoOrdered CertificateInfoOrdered::dnOnly() const { - return orderedDNOnly(*this); + return orderedDNOnly(*this); } /** @@ -601,239 +592,239 @@ class QCA_EXPORT CertificateOptions { public: - /** - Create a Certificate options set + /** + Create a Certificate options set - \param format the format to create the certificate request in - */ - CertificateOptions(CertificateRequestFormat format = PKCS10); + \param format the format to create the certificate request in + */ + CertificateOptions(CertificateRequestFormat format = PKCS10); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the Certificate Options to copy into this object - */ - CertificateOptions(const CertificateOptions &from); - ~CertificateOptions(); + \param from the Certificate Options to copy into this object + */ + CertificateOptions(const CertificateOptions &from); + ~CertificateOptions(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the Certificate Options to copy into this object - */ - CertificateOptions & operator=(const CertificateOptions &from); + \param from the Certificate Options to copy into this object + */ + CertificateOptions &operator=(const CertificateOptions &from); - /** - test the format type for this certificate - */ - CertificateRequestFormat format() const; + /** + test the format type for this certificate + */ + CertificateRequestFormat format() const; - /** - Specify the format for this certificate + /** + Specify the format for this certificate - \param f the format to use - */ - void setFormat(CertificateRequestFormat f); + \param f the format to use + */ + void setFormat(CertificateRequestFormat f); - /** - Test if the certificate options object is valid + /** + Test if the certificate options object is valid - \return true if the certificate options object is valid - */ - bool isValid() const; + \return true if the certificate options object is valid + */ + bool isValid() const; - /** - The challenge part of the certificate + /** + The challenge part of the certificate - For CertificateRequest only + For CertificateRequest only - \sa setChallenge - */ - QString challenge() const; + \sa setChallenge + */ + QString challenge() const; - /** - Information on the subject of the certificate + /** + Information on the subject of the certificate - \sa setInfo - */ - CertificateInfo info() const; + \sa setInfo + */ + CertificateInfo info() const; - /** - Information on the subject of the certificate, in the - exact order the items will be written + /** + Information on the subject of the certificate, in the + exact order the items will be written - \sa setInfoOrdered - */ - CertificateInfoOrdered infoOrdered() const; + \sa setInfoOrdered + */ + CertificateInfoOrdered infoOrdered() const; - /** - List the constraints on this certificate - */ - Constraints constraints() const; + /** + List the constraints on this certificate + */ + Constraints constraints() const; - /** - list the policies on this certificate - */ - QStringList policies() const; + /** + list the policies on this certificate + */ + QStringList policies() const; - /** - list of URI locations for CRL files + /** + list of URI locations for CRL files - each URI refers to the same CRL file + each URI refers to the same CRL file - For Certificate creation only - */ - QStringList crlLocations() const; + For Certificate creation only + */ + QStringList crlLocations() const; - /** - list of URI locations for issuer certificate files + /** + list of URI locations for issuer certificate files - each URI refers to the same issuer file + each URI refers to the same issuer file - For Certificate creation only - */ - QStringList issuerLocations() const; + For Certificate creation only + */ + QStringList issuerLocations() const; - /** - list of URI locations for OCSP services + /** + list of URI locations for OCSP services - For Certificate creation only - */ - QStringList ocspLocations() const; + For Certificate creation only + */ + QStringList ocspLocations() const; - /** - test if the certificate is a CA cert + /** + test if the certificate is a CA cert - \sa setAsCA - \sa setAsUser - */ - bool isCA() const; + \sa setAsCA + \sa setAsUser + */ + bool isCA() const; - /** - return the path limit on this certificate - */ - int pathLimit() const; + /** + return the path limit on this certificate + */ + int pathLimit() const; - /** - The serial number for the certificate + /** + The serial number for the certificate - For Certificate creation only - */ - BigInteger serialNumber() const; + For Certificate creation only + */ + BigInteger serialNumber() const; - /** - the first time the certificate will be valid + /** + the first time the certificate will be valid - For Certificate creation only - */ - QDateTime notValidBefore() const; + For Certificate creation only + */ + QDateTime notValidBefore() const; - /** - the last time the certificate is valid + /** + the last time the certificate is valid - For Certificate creation only - */ - QDateTime notValidAfter() const; + For Certificate creation only + */ + QDateTime notValidAfter() const; - /** - Specify the challenge associated with this - certificate + /** + Specify the challenge associated with this + certificate - \param s the challenge string + \param s the challenge string - \sa challenge() - */ - void setChallenge(const QString &s); + \sa challenge() + */ + void setChallenge(const QString &s); - /** - Specify information for the subject associated with the - certificate + /** + Specify information for the subject associated with the + certificate - \param info the information for the subject + \param info the information for the subject - \sa info() - */ - void setInfo(const CertificateInfo &info); + \sa info() + */ + void setInfo(const CertificateInfo &info); - /** - Specify information for the subject associated with the - certificate + /** + Specify information for the subject associated with the + certificate - \param info the information for the subject + \param info the information for the subject - \sa info() - */ - void setInfoOrdered(const CertificateInfoOrdered &info); + \sa info() + */ + void setInfoOrdered(const CertificateInfoOrdered &info); - /** - set the constraints on the certificate + /** + set the constraints on the certificate - \param constraints the constraints to be used for the certificate - */ - void setConstraints(const Constraints &constraints); + \param constraints the constraints to be used for the certificate + */ + void setConstraints(const Constraints &constraints); - /** - set the policies on the certificate + /** + set the policies on the certificate - \param policies the policies to be used for the certificate - */ - void setPolicies(const QStringList &policies); + \param policies the policies to be used for the certificate + */ + void setPolicies(const QStringList &policies); - /** - set the CRL locations of the certificate + /** + set the CRL locations of the certificate - each location refers to the same CRL. + each location refers to the same CRL. - \param locations a list of URIs to CRL files - */ - void setCRLLocations(const QStringList &locations); + \param locations a list of URIs to CRL files + */ + void setCRLLocations(const QStringList &locations); - /** - set the issuer certificate locations of the certificate + /** + set the issuer certificate locations of the certificate - each location refers to the same issuer file. + each location refers to the same issuer file. - \param locations a list of URIs to issuer certificate files - */ - void setIssuerLocations(const QStringList &locations); + \param locations a list of URIs to issuer certificate files + */ + void setIssuerLocations(const QStringList &locations); - /** - set the OCSP service locations of the certificate + /** + set the OCSP service locations of the certificate - \param locations a list of URIs to OCSP services - */ - void setOCSPLocations(const QStringList &locations); + \param locations a list of URIs to OCSP services + */ + void setOCSPLocations(const QStringList &locations); - /** - set the certificate to be a CA cert + /** + set the certificate to be a CA cert - \param pathLimit the number of intermediate certificates allowable - */ - void setAsCA(int pathLimit = 8); // value from Botan + \param pathLimit the number of intermediate certificates allowable + */ + void setAsCA(int pathLimit = 8); // value from Botan - /** - set the certificate to be a user cert (this is the default) - */ - void setAsUser(); + /** + set the certificate to be a user cert (this is the default) + */ + void setAsUser(); - /** - Set the serial number property on this certificate + /** + Set the serial number property on this certificate - \param i the serial number to use - */ - void setSerialNumber(const BigInteger &i); + \param i the serial number to use + */ + void setSerialNumber(const BigInteger &i); - /** - Set the validity period for the certificate + /** + Set the validity period for the certificate - \param start the first time this certificate becomes valid - \param end the last time this certificate is valid - */ - void setValidityPeriod(const QDateTime &start, const QDateTime &end); + \param start the first time this certificate becomes valid + \param end the last time this certificate is valid + */ + void setValidityPeriod(const QDateTime &start, const QDateTime &end); private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -848,338 +839,338 @@ class QCA_EXPORT Certificate : public Algorithm { public: - /** - Create an empty Certificate - */ - Certificate(); - - /** - Create a Certificate from a PEM encoded file - - \param fileName the name (and path, if required) - of the file that contains the PEM encoded certificate - */ - Certificate(const QString &fileName); - - /** - Create a Certificate with specified options and a specified private - key - - \param opts the options to use - \param key the private key for this certificate - \param provider the provider to use to create this key, if a - particular provider is required - */ - Certificate(const CertificateOptions &opts, const PrivateKey &key, const QString &provider = QString()); - - /** - Standard copy constructor - - \param from the certificate to copy from - */ - Certificate(const Certificate &from); - - ~Certificate(); - - /** - Standard assignment operator - - \param from the Certificate to assign from - */ - Certificate & operator=(const Certificate &from); - - /** - Test if the certificate is empty (null) - \return true if the certificate is null - */ - bool isNull() const; - - /** - The earliest date that the certificate is valid - */ - QDateTime notValidBefore() const; - - /** - The latest date that the certificate is valid - */ - QDateTime notValidAfter() const; - - /** - Properties of the subject of the certificate, as a QMultiMap - - This is the method that provides information on the - subject organisation, common name, DNS name, and so - on. The list of information types (i.e. the key to - the multi-map) is a CertificateInfoType. The values - are a list of QString. - - An example of how you can iterate over the list is: - \code -foreach( QString dns, info.values(QCA::DNS) ) -{ - std::cout << " " << qPrintable(dns) << std::endl; -} - \endcode - */ - CertificateInfo subjectInfo() const; - - /** - Properties of the subject of the certificate, as - an ordered list (QList of CertificateInfoPair). - - This allows access to the certificate information - in the same order as they appear in a certificate. - Each pair in the list has a type and a value. - - For example: - \code -CertificateInfoOrdered info = cert.subjectInfoOrdered(); -// info[0].type == CommonName -// info[0].value == "example.com" - \endcode - - \sa subjectInfo for an unordered version - \sa issuerInfoOrdered for the ordered information on the issuer - \sa CertificateInfoPair for the elements in the list - */ - CertificateInfoOrdered subjectInfoOrdered() const; - - /** - Properties of the issuer of the certificate - - \sa subjectInfo for how the return value works. - */ - CertificateInfo issuerInfo() const; - - /** - Properties of the issuer of the certificate, as - an ordered list (QList of CertificateInfoPair). - - This allows access to the certificate information - in the same order as they appear in a certificate. - Each pair in the list has a type and a value. - - \sa issuerInfo for an unordered version - \sa subjectInfoOrdered for the ordered information on the subject - \sa CertificateInfoPair for the elements in the list - */ - CertificateInfoOrdered issuerInfoOrdered() const; - - /** - The constraints that apply to this certificate - */ - Constraints constraints() const; - - /** - The policies that apply to this certificate - - Policies are specified as strings containing OIDs - */ - QStringList policies() const; - - /** - List of URI locations for CRL files - - Each URI refers to the same CRL file - */ - QStringList crlLocations() const; - - /** - List of URI locations for issuer certificate files - - Each URI refers to the same issuer file - */ - QStringList issuerLocations() const; - - /** - List of URI locations for OCSP services - */ - QStringList ocspLocations() const; - - /** - The common name of the subject of the certificate - - Common names are normally the name of a person, company or - organisation - */ - QString commonName() const; - - /** - The serial number of the certificate - */ - BigInteger serialNumber() const; - - /** - The public key associated with the subject of the certificate - */ - PublicKey subjectPublicKey() const; - - /** - Test if the Certificate is valid as a Certificate Authority - - \return true if the Certificate is valid as a Certificate Authority - */ - bool isCA() const; - - /** - Test if the Certificate is self-signed - - \return true if the certificate is self-signed - */ - bool isSelfSigned() const; - - /** - Test if the Certificate has signed another Certificate - object and is therefore the issuer - - \param other the certificate to test - - \return true if this certificate is the issuer of the argument - */ - bool isIssuerOf(const Certificate &other) const; - - /** - The upper bound of the number of links in the certificate - chain, if any - */ - int pathLimit() const; - - /** - The signature algorithm used for the signature on this certificate - */ - SignatureAlgorithm signatureAlgorithm() const; - - /** - The key identifier associated with the subject - */ - QByteArray subjectKeyId() const; - - /** - The key identifier associated with the issuer - */ - QByteArray issuerKeyId() const; - - /** - Check the validity of a certificate - - \param trusted a collection of trusted certificates - \param untrusted a collection of additional certificates, not - necessarily trusted - \param u the use required for the certificate - \param vf the conditions to validate - - \note This function may block - */ - Validity validate(const CertificateCollection &trusted, const CertificateCollection &untrusted, UsageMode u = UsageAny, ValidateFlags vf = ValidateAll) const; - - /** - Export the Certificate into a DER format - */ - QByteArray toDER() const; - - /** - Export the Certificate into a PEM format - */ - QString toPEM() const; - - /** - Export the Certificate into PEM format in a file - - \param fileName the name of the file to use - */ - bool toPEMFile(const QString &fileName) const; - - /** - Import the certificate from DER - - \param a the array containing the certificate in DER format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required - - \return the Certificate corresponding to the certificate in the - provided array - */ - static Certificate fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); - - /** - Import the certificate from PEM format - - \param s the string containing the certificate in PEM format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required - - \return the Certificate corresponding to the certificate in the - provided string - */ - static Certificate fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); - - /** - Import the certificate from a file - - \param fileName the name (and path, if required) of the file - containing the certificate in PEM format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required - - \return the Certificate corresponding to the certificate in the - provided string - */ - static Certificate fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); - - /** - Test if the subject of the certificate matches a specified host - name - - This will return true (indicating a match), if the specified host - name meets the RFC 2818 validation rules with this certificate. - - If the host is an internationalized domain name, then it must be - provided in unicode format, not in IDNA ACE/punycode format. - - \param host the name of the host to compare to - */ - bool matchesHostName(const QString &host) const; - - /** - Test for equality of two certificates - - \param a the certificate to compare this certificate with - - \return true if the two certificates are the same - */ - bool operator==(const Certificate &a) const; - - /** - Inequality operator + /** + Create an empty Certificate + */ + Certificate(); + + /** + Create a Certificate from a PEM encoded file + + \param fileName the name (and path, if required) + of the file that contains the PEM encoded certificate + */ + Certificate(const QString &fileName); + + /** + Create a Certificate with specified options and a specified private + key + + \param opts the options to use + \param key the private key for this certificate + \param provider the provider to use to create this key, if a + particular provider is required + */ + Certificate(const CertificateOptions &opts, const PrivateKey &key, const QString &provider = QString()); + + /** + Standard copy constructor + + \param from the certificate to copy from + */ + Certificate(const Certificate &from); + + ~Certificate(); + + /** + Standard assignment operator + + \param from the Certificate to assign from + */ + Certificate &operator=(const Certificate &from); + + /** + Test if the certificate is empty (null) + \return true if the certificate is null + */ + bool isNull() const; + + /** + The earliest date that the certificate is valid + */ + QDateTime notValidBefore() const; + + /** + The latest date that the certificate is valid + */ + QDateTime notValidAfter() const; + + /** + Properties of the subject of the certificate, as a QMultiMap + + This is the method that provides information on the + subject organisation, common name, DNS name, and so + on. The list of information types (i.e. the key to + the multi-map) is a CertificateInfoType. The values + are a list of QString. + + An example of how you can iterate over the list is: + \code + foreach( QString dns, info.values(QCA::DNS) ) + { + std::cout << " " << qPrintable(dns) << std::endl; + } + \endcode + */ + CertificateInfo subjectInfo() const; + + /** + Properties of the subject of the certificate, as + an ordered list (QList of CertificateInfoPair). + + This allows access to the certificate information + in the same order as they appear in a certificate. + Each pair in the list has a type and a value. + + For example: + \code + CertificateInfoOrdered info = cert.subjectInfoOrdered(); + // info[0].type == CommonName + // info[0].value == "example.com" + \endcode + + \sa subjectInfo for an unordered version + \sa issuerInfoOrdered for the ordered information on the issuer + \sa CertificateInfoPair for the elements in the list + */ + CertificateInfoOrdered subjectInfoOrdered() const; + + /** + Properties of the issuer of the certificate + + \sa subjectInfo for how the return value works. + */ + CertificateInfo issuerInfo() const; + + /** + Properties of the issuer of the certificate, as + an ordered list (QList of CertificateInfoPair). + + This allows access to the certificate information + in the same order as they appear in a certificate. + Each pair in the list has a type and a value. + + \sa issuerInfo for an unordered version + \sa subjectInfoOrdered for the ordered information on the subject + \sa CertificateInfoPair for the elements in the list + */ + CertificateInfoOrdered issuerInfoOrdered() const; + + /** + The constraints that apply to this certificate + */ + Constraints constraints() const; + + /** + The policies that apply to this certificate + + Policies are specified as strings containing OIDs + */ + QStringList policies() const; + + /** + List of URI locations for CRL files + + Each URI refers to the same CRL file + */ + QStringList crlLocations() const; + + /** + List of URI locations for issuer certificate files + + Each URI refers to the same issuer file + */ + QStringList issuerLocations() const; + + /** + List of URI locations for OCSP services + */ + QStringList ocspLocations() const; + + /** + The common name of the subject of the certificate + + Common names are normally the name of a person, company or + organisation + */ + QString commonName() const; + + /** + The serial number of the certificate + */ + BigInteger serialNumber() const; + + /** + The public key associated with the subject of the certificate + */ + PublicKey subjectPublicKey() const; + + /** + Test if the Certificate is valid as a Certificate Authority + + \return true if the Certificate is valid as a Certificate Authority + */ + bool isCA() const; + + /** + Test if the Certificate is self-signed + + \return true if the certificate is self-signed + */ + bool isSelfSigned() const; + + /** + Test if the Certificate has signed another Certificate + object and is therefore the issuer + + \param other the certificate to test + + \return true if this certificate is the issuer of the argument + */ + bool isIssuerOf(const Certificate &other) const; + + /** + The upper bound of the number of links in the certificate + chain, if any + */ + int pathLimit() const; + + /** + The signature algorithm used for the signature on this certificate + */ + SignatureAlgorithm signatureAlgorithm() const; + + /** + The key identifier associated with the subject + */ + QByteArray subjectKeyId() const; + + /** + The key identifier associated with the issuer + */ + QByteArray issuerKeyId() const; + + /** + Check the validity of a certificate + + \param trusted a collection of trusted certificates + \param untrusted a collection of additional certificates, not + necessarily trusted + \param u the use required for the certificate + \param vf the conditions to validate + + \note This function may block + */ + Validity validate(const CertificateCollection &trusted, const CertificateCollection &untrusted, UsageMode u = UsageAny, ValidateFlags vf = ValidateAll) const; + + /** + Export the Certificate into a DER format + */ + QByteArray toDER() const; + + /** + Export the Certificate into a PEM format + */ + QString toPEM() const; + + /** + Export the Certificate into PEM format in a file + + \param fileName the name of the file to use + */ + bool toPEMFile(const QString &fileName) const; + + /** + Import the certificate from DER + + \param a the array containing the certificate in DER format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required + + \return the Certificate corresponding to the certificate in the + provided array + */ + static Certificate fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); + + /** + Import the certificate from PEM format + + \param s the string containing the certificate in PEM format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required + + \return the Certificate corresponding to the certificate in the + provided string + */ + static Certificate fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); + + /** + Import the certificate from a file + + \param fileName the name (and path, if required) of the file + containing the certificate in PEM format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required + + \return the Certificate corresponding to the certificate in the + provided string + */ + static Certificate fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); + + /** + Test if the subject of the certificate matches a specified host + name + + This will return true (indicating a match), if the specified host + name meets the RFC 2818 validation rules with this certificate. + + If the host is an internationalized domain name, then it must be + provided in unicode format, not in IDNA ACE/punycode format. + + \param host the name of the host to compare to + */ + bool matchesHostName(const QString &host) const; + + /** + Test for equality of two certificates + + \param a the certificate to compare this certificate with + + \return true if the two certificates are the same + */ + bool operator==(const Certificate &a) const; + + /** + Inequality operator - \param other the certificate to compare this certificate with - */ - inline bool operator!=(const Certificate &other) const - { - return !(*this == other); - } - - /** - \internal + \param other the certificate to compare this certificate with + */ + inline bool operator!=(const Certificate &other) const + { + return !(*this == other); + } + + /** + \internal - \param c context (internal) - */ - void change(CertContext *c); + \param c context (internal) + */ + void change(CertContext *c); private: - class Private; - friend class Private; - QSharedDataPointer d; + class Private; + friend class Private; + QSharedDataPointer d; - friend class CertificateChain; - Validity chain_validate(const CertificateChain &chain, const CertificateCollection &trusted, const QList &untrusted_crls, UsageMode u, ValidateFlags vf) const; - CertificateChain chain_complete(const CertificateChain &chain, const QList &issuers, Validity *result) const; + friend class CertificateChain; + Validity chain_validate(const CertificateChain &chain, const CertificateCollection &trusted, const QList &untrusted_crls, UsageMode u, ValidateFlags vf) const; + CertificateChain chain_complete(const CertificateChain &chain, const QList &issuers, Validity *result) const; }; /** @@ -1207,77 +1198,85 @@ class CertificateChain : public QList { public: - /** - Create an empty certificate chain - */ - inline CertificateChain() {} - - /** - Create a certificate chain, starting at the specified certificate - - \param primary the end-user certificate that forms one end of the - chain - */ - inline CertificateChain(const Certificate &primary) { append(primary); } - - /** - Return the primary (end-user) Certificate - */ - inline const Certificate & primary() const { return first(); } - - /** - Check the validity of a certificate chain - - \param trusted a collection of trusted certificates - \param untrusted_crls a list of additional CRLs, not necessarily - trusted - \param u the use required for the primary certificate - \param vf the conditions to validate - - \note This function may block - - \sa Certificate::validate() - */ - inline Validity validate(const CertificateCollection &trusted, const QList &untrusted_crls = QList(), UsageMode u = UsageAny, ValidateFlags vf = ValidateAll) const; - - /** - Complete a certificate chain for the primary certificate, using the - rest of the certificates in the chain object, as well as those in - \a issuers, as possible issuers in the chain. If there are issuers - missing, then the chain might be incomplete (at the worst case, if - no issuers exist for the primary certificate, then the resulting - chain will consist of just the primary certificate). Use the - \a result argument to find out if there was a problem during - completion. A result of ValidityGood means the chain was completed - successfully. - - The newly constructed CertificateChain is returned. - - If the certificate chain is empty, then this will return an empty - CertificateChain object. - - \param issuers a pool of issuers to draw from as necessary - \param result the result of the completion operation - - \note This function may block - - \sa validate - */ - inline CertificateChain complete(const QList &issuers = QList(), Validity *result = 0) const; + /** + Create an empty certificate chain + */ + inline CertificateChain() {} + + /** + Create a certificate chain, starting at the specified certificate + + \param primary the end-user certificate that forms one end of the + chain + */ + inline CertificateChain(const Certificate &primary) + { + append(primary); + } + + /** + Return the primary (end-user) Certificate + */ + inline const Certificate &primary() const + { + return first(); + } + + /** + Check the validity of a certificate chain + + \param trusted a collection of trusted certificates + \param untrusted_crls a list of additional CRLs, not necessarily + trusted + \param u the use required for the primary certificate + \param vf the conditions to validate + + \note This function may block + + \sa Certificate::validate() + */ + inline Validity validate(const CertificateCollection &trusted, const QList &untrusted_crls = QList(), UsageMode u = UsageAny, ValidateFlags vf = ValidateAll) const; + + /** + Complete a certificate chain for the primary certificate, using the + rest of the certificates in the chain object, as well as those in + \a issuers, as possible issuers in the chain. If there are issuers + missing, then the chain might be incomplete (at the worst case, if + no issuers exist for the primary certificate, then the resulting + chain will consist of just the primary certificate). Use the + \a result argument to find out if there was a problem during + completion. A result of ValidityGood means the chain was completed + successfully. + + The newly constructed CertificateChain is returned. + + If the certificate chain is empty, then this will return an empty + CertificateChain object. + + \param issuers a pool of issuers to draw from as necessary + \param result the result of the completion operation + + \note This function may block + + \sa validate + */ + inline CertificateChain complete(const QList &issuers = QList(), Validity *result = 0) const; }; inline Validity CertificateChain::validate(const CertificateCollection &trusted, const QList &untrusted_crls, UsageMode u, ValidateFlags vf) const { - if(isEmpty()) - return ErrorValidityUnknown; - return first().chain_validate(*this, trusted, untrusted_crls, u, vf); + if (isEmpty()) { + return ErrorValidityUnknown; + } + return first().chain_validate(*this, trusted, untrusted_crls, u, vf); } inline CertificateChain CertificateChain::complete(const QList &issuers, Validity *result) const { - if(isEmpty()) - return CertificateChain(); - return first().chain_complete(*this, issuers, result); + if (isEmpty()) { + return CertificateChain(); + } + return first().chain_complete(*this, issuers, result); } /** @@ -1292,265 +1291,265 @@ class QCA_EXPORT CertificateRequest : public Algorithm { public: - /** - Create an empty certificate request - */ - CertificateRequest(); + /** + Create an empty certificate request + */ + CertificateRequest(); - /** - Create a certificate request based on the contents of a file + /** + Create a certificate request based on the contents of a file - \param fileName the file (and path, if necessary) containing a PEM - encoded certificate request - */ - CertificateRequest(const QString &fileName); + \param fileName the file (and path, if necessary) containing a PEM + encoded certificate request + */ + CertificateRequest(const QString &fileName); - /** - Create a certificate request based on specified options + /** + Create a certificate request based on specified options - \param opts the options to use in the certificate request - \param key the private key that matches the certificate being - requested - \param provider the provider to use, if a specific provider is - required - */ - CertificateRequest(const CertificateOptions &opts, const PrivateKey &key, const QString &provider = QString()); + \param opts the options to use in the certificate request + \param key the private key that matches the certificate being + requested + \param provider the provider to use, if a specific provider is + required + */ + CertificateRequest(const CertificateOptions &opts, const PrivateKey &key, const QString &provider = QString()); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the request to copy from - */ - CertificateRequest(const CertificateRequest &from); + \param from the request to copy from + */ + CertificateRequest(const CertificateRequest &from); - ~CertificateRequest(); + ~CertificateRequest(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the request to assign from - */ - CertificateRequest & operator=(const CertificateRequest &from); + \param from the request to assign from + */ + CertificateRequest &operator=(const CertificateRequest &from); - /** - test if the certificate request is empty + /** + test if the certificate request is empty - \return true if the certificate request is empty, otherwise false - */ - bool isNull() const; + \return true if the certificate request is empty, otherwise false + */ + bool isNull() const; - /** - Test if the certificate request can use a specified format + /** + Test if the certificate request can use a specified format - \param f the format to test for - \param provider the provider to use, if a specific provider is - required + \param f the format to test for + \param provider the provider to use, if a specific provider is + required - \return true if the certificate request can use the specified - format - */ - static bool canUseFormat(CertificateRequestFormat f, const QString &provider = QString()); + \return true if the certificate request can use the specified + format + */ + static bool canUseFormat(CertificateRequestFormat f, const QString &provider = QString()); - /** - the format that this Certificate request is in - */ - CertificateRequestFormat format() const; + /** + the format that this Certificate request is in + */ + CertificateRequestFormat format() const; - /** - Information on the subject of the certificate being requested + /** + Information on the subject of the certificate being requested - \note this only applies to PKCS#10 format certificate requests + \note this only applies to PKCS#10 format certificate requests - \sa subjectInfoOrdered for a version that maintains order - in the subject information. - */ - CertificateInfo subjectInfo() const; + \sa subjectInfoOrdered for a version that maintains order + in the subject information. + */ + CertificateInfo subjectInfo() const; - /** - Information on the subject of the certificate being requested, as - an ordered list (QList of CertificateInfoPair). + /** + Information on the subject of the certificate being requested, as + an ordered list (QList of CertificateInfoPair). - \note this only applies to PKCS#10 format certificate requests + \note this only applies to PKCS#10 format certificate requests - \sa subjectInfo for a version that does not maintain order, but - allows access based on a multimap. - \sa CertificateInfoPair for the elements in the list - */ - CertificateInfoOrdered subjectInfoOrdered() const; + \sa subjectInfo for a version that does not maintain order, but + allows access based on a multimap. + \sa CertificateInfoPair for the elements in the list + */ + CertificateInfoOrdered subjectInfoOrdered() const; - /** - The constraints that apply to this certificate request + /** + The constraints that apply to this certificate request - \note this only applies to PKCS#10 format certificate requests - */ - Constraints constraints() const; + \note this only applies to PKCS#10 format certificate requests + */ + Constraints constraints() const; - /** - The policies that apply to this certificate request + /** + The policies that apply to this certificate request - \note this only applies to PKCS#10 format certificate requests - */ - QStringList policies() const; + \note this only applies to PKCS#10 format certificate requests + */ + QStringList policies() const; - /** - The public key belonging to the issuer - */ - PublicKey subjectPublicKey() const; + /** + The public key belonging to the issuer + */ + PublicKey subjectPublicKey() const; - /** - Test if this Certificate Request is for a Certificate Authority - certificate + /** + Test if this Certificate Request is for a Certificate Authority + certificate - \note this only applies to PKCS#10 format certificate requests - */ - bool isCA() const; + \note this only applies to PKCS#10 format certificate requests + */ + bool isCA() const; - /** - The path limit for the certificate in this Certificate Request + /** + The path limit for the certificate in this Certificate Request - \note this only applies to PKCS#10 format certificate requests - */ - int pathLimit() const; + \note this only applies to PKCS#10 format certificate requests + */ + int pathLimit() const; - /** - The challenge associated with this certificate request - */ - QString challenge() const; + /** + The challenge associated with this certificate request + */ + QString challenge() const; - /** - The algorithm used to make the signature on this certificate - request - */ - SignatureAlgorithm signatureAlgorithm() const; + /** + The algorithm used to make the signature on this certificate + request + */ + SignatureAlgorithm signatureAlgorithm() const; - /** - Test for equality of two certificate requests + /** + Test for equality of two certificate requests - \param csr the certificate request to be compared to this certificate request + \param csr the certificate request to be compared to this certificate request - \return true if the two certificate requests are the same - */ - bool operator==(const CertificateRequest &csr) const; + \return true if the two certificate requests are the same + */ + bool operator==(const CertificateRequest &csr) const; - /** - Inequality operator + /** + Inequality operator - \param other the certificate request to be compared to this certificate request - */ - inline bool operator!=(const CertificateRequest &other) const - { - return !(*this == other); - } + \param other the certificate request to be compared to this certificate request + */ + inline bool operator!=(const CertificateRequest &other) const + { + return !(*this == other); + } - /** - Export the Certificate Request into a DER format + /** + Export the Certificate Request into a DER format - \note this only applies to PKCS#10 format certificate requests - */ - QByteArray toDER() const; + \note this only applies to PKCS#10 format certificate requests + */ + QByteArray toDER() const; - /** - Export the Certificate Request into a PEM format + /** + Export the Certificate Request into a PEM format - \note this only applies to PKCS#10 format certificate requests - */ - QString toPEM() const; + \note this only applies to PKCS#10 format certificate requests + */ + QString toPEM() const; - /** - Export the Certificate into PEM format in a file + /** + Export the Certificate into PEM format in a file - \param fileName the name of the file to use + \param fileName the name of the file to use - \note this only applies to PKCS#10 format certificate requests - */ - bool toPEMFile(const QString &fileName) const; + \note this only applies to PKCS#10 format certificate requests + */ + bool toPEMFile(const QString &fileName) const; - /** - Import the certificate request from DER + /** + Import the certificate request from DER - \param a the array containing the certificate request in DER format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + \param a the array containing the certificate request in DER format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CertificateRequest corresponding to the certificate - request in the provided array + \return the CertificateRequest corresponding to the certificate + request in the provided array - \note this only applies to PKCS#10 format certificate requests - */ - static CertificateRequest fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); + \note this only applies to PKCS#10 format certificate requests + */ + static CertificateRequest fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); - /** - Import the certificate request from PEM format + /** + Import the certificate request from PEM format - \param s the string containing the certificate request in PEM - format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + \param s the string containing the certificate request in PEM + format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CertificateRequest corresponding to the certificate - request in the provided string + \return the CertificateRequest corresponding to the certificate + request in the provided string - \note this only applies to PKCS#10 format certificate requests - */ - static CertificateRequest fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); + \note this only applies to PKCS#10 format certificate requests + */ + static CertificateRequest fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); - /** - Import the certificate request from a file + /** + Import the certificate request from a file - \param fileName the name (and path, if required) of the file - containing the certificate request in PEM format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + \param fileName the name (and path, if required) of the file + containing the certificate request in PEM format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CertificateRequest corresponding to the certificate - request in the provided string + \return the CertificateRequest corresponding to the certificate + request in the provided string - \note this only applies to PKCS#10 format certificate requests - */ - static CertificateRequest fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); + \note this only applies to PKCS#10 format certificate requests + */ + static CertificateRequest fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); - /** - Export the CertificateRequest to a string + /** + Export the CertificateRequest to a string - \return the string corresponding to the certificate request + \return the string corresponding to the certificate request - \note this only applies to SPKAC format certificate requests - */ - QString toString() const; + \note this only applies to SPKAC format certificate requests + */ + QString toString() const; - /** - Import the CertificateRequest from a string + /** + Import the CertificateRequest from a string - \param s the string containing to the certificate request - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + \param s the string containing to the certificate request + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CertificateRequest corresponding to the certificate - request in the provided string + \return the CertificateRequest corresponding to the certificate + request in the provided string - \note this only applies to SPKAC format certificate requests - */ - static CertificateRequest fromString(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); + \note this only applies to SPKAC format certificate requests + */ + static CertificateRequest fromString(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); - /** - \internal + /** + \internal - \param c context (internal) - */ - void change(CSRContext *c); + \param c context (internal) + */ + void change(CSRContext *c); private: - class Private; - friend class Private; - QSharedDataPointer d; + class Private; + friend class Private; + QSharedDataPointer d; }; /** @@ -1563,120 +1562,119 @@ class QCA_EXPORT CRLEntry { public: - /** - The reason why the certificate has been revoked - */ - enum Reason - { - Unspecified, ///< reason is unknown - KeyCompromise, ///< private key has been compromised - CACompromise, ///< certificate authority has been compromised - AffiliationChanged, - Superseded, ///< certificate has been superseded - CessationOfOperation, - CertificateHold, ///< certificate is on hold - RemoveFromCRL, ///< certificate was previously in a CRL, but is now valid - PrivilegeWithdrawn, - AACompromise ///< attribute authority has been compromised - }; - - /** - create an empty CRL entry - */ - CRLEntry(); - - /** - create a CRL entry - - \param c the certificate to revoke - \param r the reason that the certificate is being revoked - */ - explicit CRLEntry(const Certificate &c, Reason r = Unspecified); - - /** - create a CRL entry - - \param serial the serial number of the Certificate being revoked - \param time the time the Certificate was revoked (or will be - revoked) - \param r the reason that the certificate is being revoked - */ - CRLEntry(const BigInteger serial, const QDateTime &time, Reason r = Unspecified); - - /** - Copy constructor - - \param from the CRLEntry to copy from - */ - CRLEntry(const CRLEntry &from); - - ~CRLEntry(); - - /** - Standard assignment operator - - \param from the CRLEntry to copy from - */ - CRLEntry & operator=(const CRLEntry &from); - - /** - The serial number of the certificate that is the subject of this CRL entry - */ - BigInteger serialNumber() const; - - /** - The time this CRL entry was created - */ - QDateTime time() const; - - /** - Test if this CRL entry is empty - */ - bool isNull() const; - - /** - The reason that this CRL entry was created - - Alternatively, you might like to think of this as the reason that - the subject certificate has been revoked - */ - Reason reason() const; - - /** - Test if one CRL entry is "less than" another - - CRL entries are compared based on their serial number - - \param a the CRL entry to be compared to this CRL entry. - */ - bool operator<(const CRLEntry &a) const; - - /** - Test for equality of two CRL Entries - - \param a the CRL entry to be compared to this CRL entry. - - \return true if the two certificates are the same - */ - bool operator==(const CRLEntry &a) const; - - /** - Inequality operator - - \param other the CRL entry to be compared to this CRL entry. - */ - inline bool operator!=(const CRLEntry &other) const - { - return !(*this == other); - } + /** + The reason why the certificate has been revoked + */ + enum Reason { + Unspecified, ///< reason is unknown + KeyCompromise, ///< private key has been compromised + CACompromise, ///< certificate authority has been compromised + AffiliationChanged, + Superseded, ///< certificate has been superseded + CessationOfOperation, + CertificateHold, ///< certificate is on hold + RemoveFromCRL, ///< certificate was previously in a CRL, but is now valid + PrivilegeWithdrawn, + AACompromise ///< attribute authority has been compromised + }; + + /** + create an empty CRL entry + */ + CRLEntry(); + + /** + create a CRL entry + + \param c the certificate to revoke + \param r the reason that the certificate is being revoked + */ + explicit CRLEntry(const Certificate &c, Reason r = Unspecified); + + /** + create a CRL entry + + \param serial the serial number of the Certificate being revoked + \param time the time the Certificate was revoked (or will be + revoked) + \param r the reason that the certificate is being revoked + */ + CRLEntry(const BigInteger serial, const QDateTime &time, Reason r = Unspecified); + + /** + Copy constructor + + \param from the CRLEntry to copy from + */ + CRLEntry(const CRLEntry &from); + + ~CRLEntry(); + + /** + Standard assignment operator + + \param from the CRLEntry to copy from + */ + CRLEntry &operator=(const CRLEntry &from); + + /** + The serial number of the certificate that is the subject of this CRL entry + */ + BigInteger serialNumber() const; + + /** + The time this CRL entry was created + */ + QDateTime time() const; + + /** + Test if this CRL entry is empty + */ + bool isNull() const; + + /** + The reason that this CRL entry was created + + Alternatively, you might like to think of this as the reason that + the subject certificate has been revoked + */ + Reason reason() const; + + /** + Test if one CRL entry is "less than" another + + CRL entries are compared based on their serial number + + \param a the CRL entry to be compared to this CRL entry. + */ + bool operator<(const CRLEntry &a) const; + + /** + Test for equality of two CRL Entries + + \param a the CRL entry to be compared to this CRL entry. + + \return true if the two certificates are the same + */ + bool operator==(const CRLEntry &a) const; + + /** + Inequality operator + + \param other the CRL entry to be compared to this CRL entry. + */ + inline bool operator!=(const CRLEntry &other) const + { + return !(*this == other); + } private: - BigInteger _serial; - QDateTime _time; - Reason _reason; + BigInteger _serial; + QDateTime _time; + Reason _reason; - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -1702,176 +1700,176 @@ class QCA_EXPORT CRL : public Algorithm { public: - CRL(); + CRL(); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the revocation list to copy from - */ - CRL(const CRL &from); + \param from the revocation list to copy from + */ + CRL(const CRL &from); - ~CRL(); + ~CRL(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the revocation list to assign from - */ - CRL & operator=(const CRL &from); + \param from the revocation list to assign from + */ + CRL &operator=(const CRL &from); - /** - Test if the CRL is empty + /** + Test if the CRL is empty - \return true if the CRL is entry, otherwise return false - */ - bool isNull() const; + \return true if the CRL is entry, otherwise return false + */ + bool isNull() const; - /** - Information on the issuer of the CRL as a QMultiMap. + /** + Information on the issuer of the CRL as a QMultiMap. - \sa issuerInfoOrdered for a version that maintains the order - of information fields as per the underlying CRL. - */ - CertificateInfo issuerInfo() const; + \sa issuerInfoOrdered for a version that maintains the order + of information fields as per the underlying CRL. + */ + CertificateInfo issuerInfo() const; - /** - Information on the issuer of the CRL as an ordered list - (QList of CertificateInfoPair). + /** + Information on the issuer of the CRL as an ordered list + (QList of CertificateInfoPair). - \sa issuerInfo for a version that allows lookup based on - a multimap. - \sa CertificateInfoPair for the elements in the list - */ - CertificateInfoOrdered issuerInfoOrdered() const; + \sa issuerInfo for a version that allows lookup based on + a multimap. + \sa CertificateInfoPair for the elements in the list + */ + CertificateInfoOrdered issuerInfoOrdered() const; - /** - The CRL serial number. Note that serial numbers are a - CRL extension, and not all certificates have one. + /** + The CRL serial number. Note that serial numbers are a + CRL extension, and not all certificates have one. - \return the CRL serial number, or -1 if there is no serial number - */ - int number() const; + \return the CRL serial number, or -1 if there is no serial number + */ + int number() const; - /** - the time that this CRL became (or becomes) valid - */ - QDateTime thisUpdate() const; + /** + the time that this CRL became (or becomes) valid + */ + QDateTime thisUpdate() const; - /** - the time that this CRL will be obsoleted + /** + the time that this CRL will be obsoleted - you should obtain an updated CRL at this time - */ - QDateTime nextUpdate() const; + you should obtain an updated CRL at this time + */ + QDateTime nextUpdate() const; - /** - a list of the revoked certificates in this CRL - */ - QList revoked() const; + /** + a list of the revoked certificates in this CRL + */ + QList revoked() const; - /** - The signature algorithm used for the signature on this CRL - */ - SignatureAlgorithm signatureAlgorithm() const; + /** + The signature algorithm used for the signature on this CRL + */ + SignatureAlgorithm signatureAlgorithm() const; - /** - The key identification of the CRL issuer - */ - QByteArray issuerKeyId() const; + /** + The key identification of the CRL issuer + */ + QByteArray issuerKeyId() const; - /** - Test for equality of two %Certificate Revocation Lists + /** + Test for equality of two %Certificate Revocation Lists - \param a the CRL to be compared to this CRL + \param a the CRL to be compared to this CRL - \return true if the two CRLs are the same - */ - bool operator==(const CRL &a) const; + \return true if the two CRLs are the same + */ + bool operator==(const CRL &a) const; - /** - Inequality operator + /** + Inequality operator - \param other the CRL to be compared to this CRL - */ - inline bool operator!=(const CRL &other) const - { - return !(*this == other); - } + \param other the CRL to be compared to this CRL + */ + inline bool operator!=(const CRL &other) const + { + return !(*this == other); + } - /** - Export the %Certificate Revocation List (CRL) in DER format + /** + Export the %Certificate Revocation List (CRL) in DER format - \return an array containing the CRL in DER format - */ - QByteArray toDER() const; + \return an array containing the CRL in DER format + */ + QByteArray toDER() const; - /** - Export the %Certificate Revocation List (CRL) in PEM format + /** + Export the %Certificate Revocation List (CRL) in PEM format - \return a string containing the CRL in PEM format - */ - QString toPEM() const; + \return a string containing the CRL in PEM format + */ + QString toPEM() const; - /** - Export the %Certificate Revocation List (CRL) into PEM format in a - file - - \param fileName the name of the file to use - */ - bool toPEMFile(const QString &fileName) const; - - /** - Import a DER encoded %Certificate Revocation List (CRL) - - \param a the array containing the CRL in DER format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + /** + Export the %Certificate Revocation List (CRL) into PEM format in a + file + + \param fileName the name of the file to use + */ + bool toPEMFile(const QString &fileName) const; + + /** + Import a DER encoded %Certificate Revocation List (CRL) + + \param a the array containing the CRL in DER format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CRL corresponding to the contents of the array - */ - static CRL fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); + \return the CRL corresponding to the contents of the array + */ + static CRL fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); - /** - Import a PEM encoded %Certificate Revocation List (CRL) - - \param s the string containing the CRL in PEM format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + /** + Import a PEM encoded %Certificate Revocation List (CRL) + + \param s the string containing the CRL in PEM format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CRL corresponding to the contents of the string - */ - static CRL fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); + \return the CRL corresponding to the contents of the string + */ + static CRL fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); - /** - Import a PEM encoded %Certificate Revocation List (CRL) from a file + /** + Import a PEM encoded %Certificate Revocation List (CRL) from a file - \param fileName the name (and path, if required) of the file - containing the certificate in PEM format - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + \param fileName the name (and path, if required) of the file + containing the certificate in PEM format + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CRL in the file - */ - static CRL fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); + \return the CRL in the file + */ + static CRL fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); - /** - \internal + /** + \internal - \param c context (internal) - */ - void change(CRLContext *c); + \param c context (internal) + */ + void change(CRLContext *c); private: - class Private; - friend class Private; - QSharedDataPointer d; + class Private; + friend class Private; + QSharedDataPointer d; }; /** @@ -1890,140 +1888,140 @@ class QCA_EXPORT CertificateCollection { public: - /** - Create an empty Certificate / CRL collection - */ - CertificateCollection(); + /** + Create an empty Certificate / CRL collection + */ + CertificateCollection(); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the CertificateCollection to copy from - */ - CertificateCollection(const CertificateCollection &from); + \param from the CertificateCollection to copy from + */ + CertificateCollection(const CertificateCollection &from); - ~CertificateCollection(); + ~CertificateCollection(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the CertificateCollection to copy from - */ - CertificateCollection & operator=(const CertificateCollection &from); + \param from the CertificateCollection to copy from + */ + CertificateCollection &operator=(const CertificateCollection &from); - /** - Append a Certificate to this collection + /** + Append a Certificate to this collection - \param cert the Certificate to add to this CertificateCollection - */ - void addCertificate(const Certificate &cert); + \param cert the Certificate to add to this CertificateCollection + */ + void addCertificate(const Certificate &cert); - /** - Append a CRL to this collection + /** + Append a CRL to this collection - \param crl the certificate revokation list to add to this - CertificateCollection - */ - void addCRL(const CRL &crl); + \param crl the certificate revokation list to add to this + CertificateCollection + */ + void addCRL(const CRL &crl); - /** - The Certificates in this collection - */ - QList certificates() const; + /** + The Certificates in this collection + */ + QList certificates() const; - /** - The CRLs in this collection - */ - QList crls() const; + /** + The CRLs in this collection + */ + QList crls() const; - /** - Add another CertificateCollection to this collection + /** + Add another CertificateCollection to this collection - \param other the CertificateCollection to add to this collection - */ - void append(const CertificateCollection &other); + \param other the CertificateCollection to add to this collection + */ + void append(const CertificateCollection &other); - /** - Add another CertificateCollection to this collection + /** + Add another CertificateCollection to this collection - \param other the CertificateCollection to add to this collection - */ - CertificateCollection operator+(const CertificateCollection &other) const; + \param other the CertificateCollection to add to this collection + */ + CertificateCollection operator+(const CertificateCollection &other) const; - /** - Add another CertificateCollection to this collection + /** + Add another CertificateCollection to this collection - \param other the CertificateCollection to add to this collection - */ - CertificateCollection & operator+=(const CertificateCollection &other); + \param other the CertificateCollection to add to this collection + */ + CertificateCollection &operator+=(const CertificateCollection &other); - /** - test if the CertificateCollection can be imported and exported to - PKCS#7 format + /** + test if the CertificateCollection can be imported and exported to + PKCS#7 format - \param provider the provider to use, if a specific provider is - required + \param provider the provider to use, if a specific provider is + required - \return true if the CertificateCollection can be imported and - exported to PKCS#7 format - */ - static bool canUsePKCS7(const QString &provider = QString()); + \return true if the CertificateCollection can be imported and + exported to PKCS#7 format + */ + static bool canUsePKCS7(const QString &provider = QString()); - /** - export the CertificateCollection to a plain text file + /** + export the CertificateCollection to a plain text file - \param fileName the name (and path, if required) to write the - contents of the CertificateCollection to + \param fileName the name (and path, if required) to write the + contents of the CertificateCollection to - \return true if the export succeeded, otherwise false - */ - bool toFlatTextFile(const QString &fileName); + \return true if the export succeeded, otherwise false + */ + bool toFlatTextFile(const QString &fileName); - /** - export the CertificateCollection to a PKCS#7 file + /** + export the CertificateCollection to a PKCS#7 file - \param fileName the name (and path, if required) to write the - contents of the CertificateCollection to - \param provider the provider to use, if a specific provider is - required + \param fileName the name (and path, if required) to write the + contents of the CertificateCollection to + \param provider the provider to use, if a specific provider is + required - \return true if the export succeeded, otherwise false - */ - bool toPKCS7File(const QString &fileName, const QString &provider = QString()); + \return true if the export succeeded, otherwise false + */ + bool toPKCS7File(const QString &fileName, const QString &provider = QString()); - /** - import a CertificateCollection from a text file + /** + import a CertificateCollection from a text file - \param fileName the name (and path, if required) to read the - certificate collection from - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + \param fileName the name (and path, if required) to read the + certificate collection from + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CertificateCollection corresponding to the contents of - the file specified in fileName - */ - static CertificateCollection fromFlatTextFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); + \return the CertificateCollection corresponding to the contents of + the file specified in fileName + */ + static CertificateCollection fromFlatTextFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); - /** - import a CertificateCollection from a PKCS#7 file + /** + import a CertificateCollection from a PKCS#7 file - \param fileName the name (and path, if required) to read the - certificate collection from - \param result a pointer to a ConvertResult, which if not-null will - be set to the conversion status - \param provider the provider to use, if a specific provider is - required + \param fileName the name (and path, if required) to read the + certificate collection from + \param result a pointer to a ConvertResult, which if not-null will + be set to the conversion status + \param provider the provider to use, if a specific provider is + required - \return the CertificateCollection corresponding to the contents of - the file specified in fileName - */ - static CertificateCollection fromPKCS7File(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); + \return the CertificateCollection corresponding to the contents of + the file specified in fileName + */ + static CertificateCollection fromPKCS7File(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** @@ -2037,80 +2035,80 @@ class QCA_EXPORT CertificateAuthority : public Algorithm { public: - /** - Create a new %Certificate Authority + /** + Create a new %Certificate Authority - \param cert the CA certificate - \param key the private key associated with the CA certificate - \param provider the provider to use, if a specific provider is - required - */ - CertificateAuthority(const Certificate &cert, const PrivateKey &key, const QString &provider); + \param cert the CA certificate + \param key the private key associated with the CA certificate + \param provider the provider to use, if a specific provider is + required + */ + CertificateAuthority(const Certificate &cert, const PrivateKey &key, const QString &provider); - /** - Copy constructor + /** + Copy constructor - \param from the CertificateAuthority to copy from - */ - CertificateAuthority(const CertificateAuthority &from); + \param from the CertificateAuthority to copy from + */ + CertificateAuthority(const CertificateAuthority &from); - ~CertificateAuthority(); + ~CertificateAuthority(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the CertificateAuthority to copy from - */ - CertificateAuthority & operator=(const CertificateAuthority &from); + \param from the CertificateAuthority to copy from + */ + CertificateAuthority &operator=(const CertificateAuthority &from); - /** - The Certificate belonging to the %CertificateAuthority + /** + The Certificate belonging to the %CertificateAuthority - This is the Certificate that was passed as an argument to the - constructor - */ - Certificate certificate() const; + This is the Certificate that was passed as an argument to the + constructor + */ + Certificate certificate() const; - /** - Create a new Certificate by signing the provider CertificateRequest + /** + Create a new Certificate by signing the provider CertificateRequest - \param req the CertificateRequest to sign - \param notValidAfter the last date that the Certificate will be - valid - */ - Certificate signRequest(const CertificateRequest &req, const QDateTime ¬ValidAfter) const; + \param req the CertificateRequest to sign + \param notValidAfter the last date that the Certificate will be + valid + */ + Certificate signRequest(const CertificateRequest &req, const QDateTime ¬ValidAfter) const; - /** - Create a new Certificate + /** + Create a new Certificate - \param key the Public Key to use to create the Certificate - \param opts the options to use for the new Certificate - */ - Certificate createCertificate(const PublicKey &key, const CertificateOptions &opts) const; + \param key the Public Key to use to create the Certificate + \param opts the options to use for the new Certificate + */ + Certificate createCertificate(const PublicKey &key, const CertificateOptions &opts) const; - /** - Create a new Certificate Revocation List (CRL) + /** + Create a new Certificate Revocation List (CRL) - \param nextUpdate the date that the CRL will be updated + \param nextUpdate the date that the CRL will be updated - \return an empty CRL - */ - CRL createCRL(const QDateTime &nextUpdate) const; + \return an empty CRL + */ + CRL createCRL(const QDateTime &nextUpdate) const; - /** - Update the CRL to include new entries + /** + Update the CRL to include new entries - \param crl the CRL to update - \param entries the entries to add to the CRL - \param nextUpdate the date that this CRL will be updated + \param crl the CRL to update + \param entries the entries to add to the CRL + \param nextUpdate the date that this CRL will be updated - \return the update CRL - */ - CRL updateCRL(const CRL &crl, const QList &entries, const QDateTime &nextUpdate) const; + \return the update CRL + */ + CRL updateCRL(const CRL &crl, const QList &entries, const QDateTime &nextUpdate) const; private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -2128,225 +2126,225 @@ For more information on PKCS12 "Personal Information Exchange Syntax Standard", see ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf. + href="ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf">ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf. \ingroup UserAPI */ class QCA_EXPORT KeyBundle { public: - /** - Create an empty KeyBundle - */ - KeyBundle(); - - /** - Create a KeyBundle from a PKCS12 (.p12) encoded - file - - This constructor requires appropriate plugin (provider) - support. You must check for the "pkcs12" feature - before using this constructor. - - \param fileName the name of the file to read from - \param passphrase the passphrase that is applicable to the file - - \sa fromFile for a more flexible version of the - same capability. - - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - explicit KeyBundle(const QString &fileName, const SecureArray &passphrase = SecureArray()); - - /** - Standard copy constructor - - \param from the KeyBundle to use as source - */ - KeyBundle(const KeyBundle &from); - - ~KeyBundle(); - - /** - Standard assignment operator + /** + Create an empty KeyBundle + */ + KeyBundle(); - \param from the KeyBundle to use as source - */ - KeyBundle & operator=(const KeyBundle &from); + /** + Create a KeyBundle from a PKCS12 (.p12) encoded + file - /** - Test if this key is empty (null) - */ - bool isNull() const; - - /** - The name associated with this key. - - This is also known as the "friendly name", and if - present, is typically suitable to be displayed to - the user. - - \sa setName - */ - QString name() const; - - /** - The public certificate part of this bundle - - \sa setCertificateChainAndKey - */ - CertificateChain certificateChain() const; - - /** - The private key part of this bundle - - \sa setCertificateChainAndKey - */ - PrivateKey privateKey() const; - - /** - Specify the name of this bundle - - \param s the name to use - */ - void setName(const QString &s); - - /** - Set the public certificate and private key - - \param c the CertificateChain containing the public part of the - Bundle - \param key the private key part of the Bundle - - \sa privateKey, certificateChain for getters - */ - void setCertificateChainAndKey(const CertificateChain &c, const PrivateKey &key); - - /** - Export the key bundle to an array in PKCS12 format. - - This method requires appropriate plugin (provider) - support - you must check for the "pkcs12" feature, - as shown below. - - \code -if( QCA::isSupported("pkcs12") ) -{ - // can use I/O - byteArray = bundle.toArray( "pass phrase" ); -} -else -{ - // not possible to use I/O -} - \endcode - - \param passphrase the passphrase to use to protect the bundle - \param provider the provider to use, if a specific provider is - required - */ - QByteArray toArray(const SecureArray &passphrase, const QString &provider = QString()) const; - - /** - Export the key bundle to a file in PKCS12 (.p12) format - - This method requires appropriate plugin (provider) - support - you must check for the "pkcs12" feature, - as shown below. - - \code -if( QCA::isSupported("pkcs12") ) -{ - // can use I/O - bool result = bundle.toFile( filename, "pass phrase" ); -} -else -{ - // not possible to use I/O -} - \endcode - - \param fileName the name of the file to save to - \param passphrase the passphrase to use to protect the bundle - \param provider the provider to use, if a specific provider is - required - */ - bool toFile(const QString &fileName, const SecureArray &passphrase, const QString &provider = QString()) const; - - /** - Import the key bundle from an array in PKCS12 format - - This method requires appropriate plugin (provider) - support - you must check for the "pkcs12" feature, - as shown below. - - \code -if( QCA::isSupported("pkcs12") ) -{ - // can use I/O - bundle = QCA::KeyBundle::fromArray( array, "pass phrase" ); -} -else -{ - // not possible to use I/O -} - \endcode - - \param a the array to import from - \param passphrase the passphrase for the encoded bundle - \param result pointer to the result of the import process - \param provider the provider to use, if a specific provider is - required - - \sa QCA::KeyLoader for an asynchronous loader approach. - - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - static KeyBundle fromArray(const QByteArray &a, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); - - /** - Import the key bundle from a file in PKCS12 (.p12) format - - This method requires appropriate plugin (provider) - support - you must check for the "pkcs12" feature, - as shown below. - - \code -if( QCA::isSupported("pkcs12") ) -{ - // can use I/O - bundle = QCA::KeyBundle::fromFile( filename, "pass phrase" ); -} -else -{ - // not possible to use I/O -} - \endcode + This constructor requires appropriate plugin (provider) + support. You must check for the "pkcs12" feature + before using this constructor. - \param fileName the name of the file to read from - \param passphrase the passphrase for the encoded bundle - \param result pointer to the result of the import process - \param provider the provider to use, if a specific provider is - required + \param fileName the name of the file to read from + \param passphrase the passphrase that is applicable to the file - \sa QCA::KeyLoader for an asynchronous loader approach. + \sa fromFile for a more flexible version of the + same capability. - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - static KeyBundle fromFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + explicit KeyBundle(const QString &fileName, const SecureArray &passphrase = SecureArray()); + + /** + Standard copy constructor + + \param from the KeyBundle to use as source + */ + KeyBundle(const KeyBundle &from); + + ~KeyBundle(); + + /** + Standard assignment operator + + \param from the KeyBundle to use as source + */ + KeyBundle &operator=(const KeyBundle &from); + + /** + Test if this key is empty (null) + */ + bool isNull() const; + + /** + The name associated with this key. + + This is also known as the "friendly name", and if + present, is typically suitable to be displayed to + the user. + + \sa setName + */ + QString name() const; + + /** + The public certificate part of this bundle + + \sa setCertificateChainAndKey + */ + CertificateChain certificateChain() const; + + /** + The private key part of this bundle + + \sa setCertificateChainAndKey + */ + PrivateKey privateKey() const; + + /** + Specify the name of this bundle + + \param s the name to use + */ + void setName(const QString &s); + + /** + Set the public certificate and private key + + \param c the CertificateChain containing the public part of the + Bundle + \param key the private key part of the Bundle + + \sa privateKey, certificateChain for getters + */ + void setCertificateChainAndKey(const CertificateChain &c, const PrivateKey &key); + + /** + Export the key bundle to an array in PKCS12 format. + + This method requires appropriate plugin (provider) + support - you must check for the "pkcs12" feature, + as shown below. + + \code + if( QCA::isSupported("pkcs12") ) + { + // can use I/O + byteArray = bundle.toArray( "pass phrase" ); + } + else + { + // not possible to use I/O + } + \endcode + + \param passphrase the passphrase to use to protect the bundle + \param provider the provider to use, if a specific provider is + required + */ + QByteArray toArray(const SecureArray &passphrase, const QString &provider = QString()) const; + + /** + Export the key bundle to a file in PKCS12 (.p12) format + + This method requires appropriate plugin (provider) + support - you must check for the "pkcs12" feature, + as shown below. + + \code + if( QCA::isSupported("pkcs12") ) + { + // can use I/O + bool result = bundle.toFile( filename, "pass phrase" ); + } + else + { + // not possible to use I/O + } + \endcode + + \param fileName the name of the file to save to + \param passphrase the passphrase to use to protect the bundle + \param provider the provider to use, if a specific provider is + required + */ + bool toFile(const QString &fileName, const SecureArray &passphrase, const QString &provider = QString()) const; + + /** + Import the key bundle from an array in PKCS12 format + + This method requires appropriate plugin (provider) + support - you must check for the "pkcs12" feature, + as shown below. + + \code + if( QCA::isSupported("pkcs12") ) + { + // can use I/O + bundle = QCA::KeyBundle::fromArray( array, "pass phrase" ); + } + else + { + // not possible to use I/O + } + \endcode + + \param a the array to import from + \param passphrase the passphrase for the encoded bundle + \param result pointer to the result of the import process + \param provider the provider to use, if a specific provider is + required + + \sa QCA::KeyLoader for an asynchronous loader approach. + + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + static KeyBundle fromArray(const QByteArray &a, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); + + /** + Import the key bundle from a file in PKCS12 (.p12) format + + This method requires appropriate plugin (provider) + support - you must check for the "pkcs12" feature, + as shown below. + + \code + if( QCA::isSupported("pkcs12") ) + { + // can use I/O + bundle = QCA::KeyBundle::fromFile( filename, "pass phrase" ); + } + else + { + // not possible to use I/O + } + \endcode + + \param fileName the name of the file to read from + \param passphrase the passphrase for the encoded bundle + \param result pointer to the result of the import process + \param provider the provider to use, if a specific provider is + required + + \sa QCA::KeyLoader for an asynchronous loader approach. + + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + static KeyBundle fromFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** \class PGPKey qca_cert.h QtCrypto - Pretty Good Privacy key + Pretty Good Privacy key This holds either a reference to an item in a real PGP keyring, or a standalone item created using the from*() functions. @@ -2360,167 +2358,167 @@ class QCA_EXPORT PGPKey : public Algorithm { public: - /** - Create an empty PGP key - */ - PGPKey(); + /** + Create an empty PGP key + */ + PGPKey(); - /** - Create a PGP key from an encoded file + /** + Create a PGP key from an encoded file - \param fileName the name (and path, if required) of the file - that the PGP key is to be loaded from. + \param fileName the name (and path, if required) of the file + that the PGP key is to be loaded from. - \sa fromFile for a version that allows better error checking / validation - \sa toFile for a method to write out the key. - */ - PGPKey(const QString &fileName); + \sa fromFile for a version that allows better error checking / validation + \sa toFile for a method to write out the key. + */ + PGPKey(const QString &fileName); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the PGPKey to use as the source - */ - PGPKey(const PGPKey &from); + \param from the PGPKey to use as the source + */ + PGPKey(const PGPKey &from); - ~PGPKey(); + ~PGPKey(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the PGPKey to use as the source - */ - PGPKey & operator=(const PGPKey &from); + \param from the PGPKey to use as the source + */ + PGPKey &operator=(const PGPKey &from); - /** - Test if the PGP key is empty (null) + /** + Test if the PGP key is empty (null) - \return true if the PGP key is null - */ - bool isNull() const; + \return true if the PGP key is null + */ + bool isNull() const; - /** - The Key identification for the PGP key - */ - QString keyId() const; + /** + The Key identification for the PGP key + */ + QString keyId() const; - /** - The primary user identification for the key - */ - QString primaryUserId() const; + /** + The primary user identification for the key + */ + QString primaryUserId() const; - /** - The list of all user identifications associated with the key - */ - QStringList userIds() const; + /** + The list of all user identifications associated with the key + */ + QStringList userIds() const; - /** - Test if the PGP key is the secret key - - \return true if the PGP key is the secret key - */ - bool isSecret() const; + /** + Test if the PGP key is the secret key + + \return true if the PGP key is the secret key + */ + bool isSecret() const; - /** - The creation date for the key - */ - QDateTime creationDate() const; + /** + The creation date for the key + */ + QDateTime creationDate() const; - /** - The expiration date for the key - */ - QDateTime expirationDate() const; + /** + The expiration date for the key + */ + QDateTime expirationDate() const; - /** - The key fingerpint + /** + The key fingerpint - This will return the PGP fingerprint as a string. It comprises 40 - hex digits, without spaces. - */ - QString fingerprint() const; + This will return the PGP fingerprint as a string. It comprises 40 + hex digits, without spaces. + */ + QString fingerprint() const; - /** - Test if this key is in a keyring + /** + Test if this key is in a keyring - \return true if the key is in a keyring + \return true if the key is in a keyring - \note keys that are not in a keyring cannot be used for encryption, - decryption, signing or verification - */ - bool inKeyring() const; + \note keys that are not in a keyring cannot be used for encryption, + decryption, signing or verification + */ + bool inKeyring() const; - /** - Test if the key is trusted + /** + Test if the key is trusted - \return true if the key is trusted - */ - bool isTrusted() const; + \return true if the key is trusted + */ + bool isTrusted() const; - /** - Export the key to an array. + /** + Export the key to an array. - This will export the key in a binary format (that is, not in an - "ascii armoured" form). + This will export the key in a binary format (that is, not in an + "ascii armoured" form). - \sa fromArray for a static import method. - \sa toString for an "ascii armoured" export method. - */ - QByteArray toArray() const; + \sa fromArray for a static import method. + \sa toString for an "ascii armoured" export method. + */ + QByteArray toArray() const; - /** - Export the key to a string + /** + Export the key to a string - This will export the key in an "ascii armoured" form. + This will export the key in an "ascii armoured" form. - \sa fromString for a static import method. - \sa toArray for a binary format export method. - */ - QString toString() const; + \sa fromString for a static import method. + \sa toArray for a binary format export method. + */ + QString toString() const; - /** - Export the key to a file + /** + Export the key to a file - \param fileName the name of the file to save the key to - */ - bool toFile(const QString &fileName) const; + \param fileName the name of the file to save the key to + */ + bool toFile(const QString &fileName) const; - /** - Import the key from an array - - \param a the array to import from - \param result if not null, this will be set to the result of the - import process - \param provider the provider to use, if a particular provider is - required - */ - static PGPKey fromArray(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); - - /** - Import the key from a string - - \param s the string to import from - \param result if not null, this will be set to the result of the - import process - \param provider the provider to use, if a particular provider is - required - */ - static PGPKey fromString(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); - - /** - Import the key from a file + /** + Import the key from an array + + \param a the array to import from + \param result if not null, this will be set to the result of the + import process + \param provider the provider to use, if a particular provider is + required + */ + static PGPKey fromArray(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); + + /** + Import the key from a string + + \param s the string to import from + \param result if not null, this will be set to the result of the + import process + \param provider the provider to use, if a particular provider is + required + */ + static PGPKey fromString(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); + + /** + Import the key from a file - \param fileName string containing the name of the file to import - from - \param result if not null, this will be set to the result of the - import process - \param provider the provider to use, if a particular provider is - required - */ - static PGPKey fromFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); + \param fileName string containing the name of the file to import + from + \param result if not null, this will be set to the result of the + import process + \param provider the provider to use, if a particular provider is + required + */ + static PGPKey fromFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -2564,110 +2562,110 @@ */ class QCA_EXPORT KeyLoader : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Create a KeyLoader object. + /** + Create a KeyLoader object. - \param parent the parent object for this object - */ - KeyLoader(QObject *parent = 0); - ~KeyLoader(); + \param parent the parent object for this object + */ + KeyLoader(QObject *parent = 0); + ~KeyLoader(); - /** - Initiate an asynchronous loading of a PrivateKey from a PEM format - file. + /** + Initiate an asynchronous loading of a PrivateKey from a PEM format + file. - This function will return immediately. + This function will return immediately. - \param fileName the name of the file (and path, if necessary) to - load the key from - */ - void loadPrivateKeyFromPEMFile(const QString &fileName); + \param fileName the name of the file (and path, if necessary) to + load the key from + */ + void loadPrivateKeyFromPEMFile(const QString &fileName); - /** - Initiate an asynchronous loading of a PrivateKey from a PEM format - string. + /** + Initiate an asynchronous loading of a PrivateKey from a PEM format + string. - This function will return immediately. + This function will return immediately. - \param s the string containing the PEM formatted key - */ - void loadPrivateKeyFromPEM(const QString &s); + \param s the string containing the PEM formatted key + */ + void loadPrivateKeyFromPEM(const QString &s); - /** - Initiate an asynchronous loading of a PrivateKey from a DER format - array. + /** + Initiate an asynchronous loading of a PrivateKey from a DER format + array. - This function will return immediately. + This function will return immediately. - \param a the array containing the DER formatted key - */ - void loadPrivateKeyFromDER(const SecureArray &a); + \param a the array containing the DER formatted key + */ + void loadPrivateKeyFromDER(const SecureArray &a); - /** - Initiate an asynchronous loading of a KeyBundle from a file + /** + Initiate an asynchronous loading of a KeyBundle from a file - This function will return immediately. + This function will return immediately. - \param fileName the name of the file (and path, if necessary) to - load the key bundle from - */ - void loadKeyBundleFromFile(const QString &fileName); + \param fileName the name of the file (and path, if necessary) to + load the key bundle from + */ + void loadKeyBundleFromFile(const QString &fileName); - /** - Initiate an asynchronous loading of a KeyBundle from an array + /** + Initiate an asynchronous loading of a KeyBundle from an array - This function will return immediately. + This function will return immediately. - \param a the array containing the key bundle - */ - void loadKeyBundleFromArray(const QByteArray &a); + \param a the array containing the key bundle + */ + void loadKeyBundleFromArray(const QByteArray &a); - /** - The result of the loading process. + /** + The result of the loading process. - This is not valid until the finished() signal has been emitted. - */ - ConvertResult convertResult() const; + This is not valid until the finished() signal has been emitted. + */ + ConvertResult convertResult() const; - /** - The private key that has been loaded. + /** + The private key that has been loaded. - This is only valid if loadPrivateKeyFromPEMFile(), - loadPrivateKeyFromPEM() or loadPrivateKeyFromDER() has been used, - the load has completed (that is, finished() has been emitted), and - the conversion succeeded (that is, convertResult() returned - ConvertGood). - */ - PrivateKey privateKey() const; + This is only valid if loadPrivateKeyFromPEMFile(), + loadPrivateKeyFromPEM() or loadPrivateKeyFromDER() has been used, + the load has completed (that is, finished() has been emitted), and + the conversion succeeded (that is, convertResult() returned + ConvertGood). + */ + PrivateKey privateKey() const; - /** - The key bundle that has been loaded. + /** + The key bundle that has been loaded. - This is only valid if loadKeyBundleFromFile() or - loadKeyBundleFromArray() has been used, the load has completed - (that is, finished() has been emitted), and the conversion - succeeded (that is, convertResult() returned ConvertGood). - */ - KeyBundle keyBundle() const; + This is only valid if loadKeyBundleFromFile() or + loadKeyBundleFromArray() has been used, the load has completed + (that is, finished() has been emitted), and the conversion + succeeded (that is, convertResult() returned ConvertGood). + */ + KeyBundle keyBundle() const; Q_SIGNALS: - /** - Signal that is emitted when the load process has completed. + /** + Signal that is emitted when the load process has completed. - \note The load process may not have completed successfully - check - the result of convertResult() to confirm this before using the - privateKey() or keyBundle() results. - */ - void finished(); + \note The load process may not have completed successfully - check + the result of convertResult() to confirm this before using the + privateKey() or keyBundle() results. + */ + void finished(); private: - Q_DISABLE_COPY(KeyLoader) + Q_DISABLE_COPY(KeyLoader) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; } diff --git a/include/QtCrypto/qca_core.h b/include/QtCrypto/qca_core.h --- a/include/QtCrypto/qca_core.h +++ b/include/QtCrypto/qca_core.h @@ -87,7 +87,8 @@ /** QCA - the Qt Cryptographic Architecture */ -namespace QCA { +namespace QCA +{ class Provider; class Random; @@ -108,39 +109,37 @@ \sa ProviderListIterator \sa providers() */ -typedef QList ProviderList; +typedef QList ProviderList; /** 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. + 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 +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 Direction { + Encode, ///< Operate in the "forward" direction; for example, encrypting + Decode ///< Operate in the "reverse" direction; for example, decrypting }; /** @@ -194,11 +193,11 @@ \code QCA::init(); if(!QCA::isSupported("sha1")) - printf("SHA1 not supported!\n"); + printf("SHA1 not supported!\n"); else { - QString result = QCA::SHA1::hashToString(myString); - printf("sha1(\"%s\") = [%s]\n", myString.data(), qPrintable(result)); + QString result = QCA::SHA1::hashToString(myString); + printf("sha1(\"%s\") = [%s]\n", myString.data(), qPrintable(result)); } \endcode @@ -268,7 +267,7 @@ /** Add a provider to the current list of providers - This function allows you to add a provider to the + 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. @@ -315,7 +314,7 @@ - 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 + - 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 @@ -335,7 +334,7 @@ /** Return the priority of a specified provider - The name of the provider (eg "qca-ossl") is used to look up the + The name of the provider (eg "qca-ossl") 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. @@ -476,7 +475,7 @@ Return a reference to the %QCA Logger, which is used for diagnostics and error recording. - The system Logger is automatically created for you on start. + The system Logger is automatically created for you on start. */ QCA_EXPORT Logger *logger(); @@ -491,13 +490,13 @@ \note This is a macro, so arguments may or may not be evaluated. */ #define QCA_logTextMessage(message, severity) \ - do { \ - QCA::Logger::Severity s = severity; \ - QCA::Logger *l = QCA::logger (); \ - if (s <= l->level ()) { \ - l->logTextMessage (message, s); \ - } \ - } while (false) + do { \ + QCA::Logger::Severity s = severity; \ + QCA::Logger *l = QCA::logger (); \ + if (s <= l->level ()) { \ + l->logTextMessage (message, s); \ + } \ + } while (false) /** Log a binary message. This is an efficient function @@ -510,13 +509,13 @@ \note This is a macro, so arguments may or may not be evaluated. */ #define QCA_logBinaryMessage(blob, severity) \ - do { \ - QCA::Logger::Severity s = severity; \ - QCA::Logger *l = QCA::logger (); \ - if (s <= l->level ()) { \ - l->logBinaryMessage (blob, s); \ - } \ - } while (false) + do { \ + QCA::Logger::Severity s = severity; \ + QCA::Logger *l = QCA::logger (); \ + if (s <= l->level ()) { \ + l->logBinaryMessage (blob, s); \ + } \ + } while (false) /** Test if QCA can access the root CA certificates @@ -538,9 +537,9 @@ are used for system updates. They are provided in different ways for different systems. - This function provides an common way to access the system + This function provides an common way to access the system certificates. There are other ways to access certificates - see - the various I/O methods (such as fromDER() and fromPEM()) + the various I/O methods (such as fromDER() and fromPEM()) in the Certificate and CertificateCollection classes. \note Availability of the system certificates depends on how @@ -563,7 +562,7 @@ 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 + 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 @@ -583,7 +582,7 @@ // 0x61 is 'a' in ASCII if (QString("61616161616161616161") == QCA::arrayToHex(test) ) { - printf ("arrayToHex passed\n"); + printf ("arrayToHex passed\n"); } \endcode @@ -609,7 +608,7 @@ if (QCA::hexToArray(QString("62626262626262006262") ) == test ) { - printf ("hexToArray passed\n"); + printf ("hexToArray passed\n"); } \endcode @@ -659,15 +658,15 @@ 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). - */ - explicit Initializer(MemoryMode m = Practical, int prealloc = 64); - ~Initializer(); + /** + 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). + */ + explicit Initializer(MemoryMode m = Practical, int prealloc = 64); + ~Initializer(); }; /** @@ -697,38 +696,47 @@ 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 minimum and maximum (inclusive) - is acceptable. - */ - int multiple() const { return _multiple; } + /** + 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 minimum and maximum (inclusive) + is acceptable. + */ + int multiple() const + { + return _multiple; + } private: - const int _min, _max, _multiple; + const int _min, _max, _multiple; }; /** @@ -738,8 +746,8 @@ 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 + 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. @@ -749,167 +757,167 @@ class QCA_EXPORT Provider { public: - virtual ~Provider(); - - class Context; - - /** - 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(); - - /** - Deinitialisation routine - - This routine will be called just before provider destruction. - Notably, during QCA shutdown, deinit() will be called on all - providers before any of the providers are destructed. Use this - opportunity to free any resources that may be used by other - providers. - */ - virtual void deinit(); - - /** - Version number of the plugin - - The format is the same as QCA itself. Version 1.2.3 would be - represented as 0x010203. - - The default returns 0 (version 0.0.0). - */ - virtual int version() const; - - /** - Target QCA version for the provider. - - This is used to verify compatibility between the - provider and QCA. For a provider to be used, it - must supply major and minor version numbers here that are - less-than or equal to the actual QCA version (the patch - version number is ignored). This means an older - provider may be used with a newer QCA, but a newer - provider cannot be used with an older QCA. - */ - virtual int qcaVersion() const = 0; - - /** - 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(sha1)"; - return list; -} - \endcode - */ - virtual QStringList features() const = 0; - - /** - Optional credit text for the provider. - - You might display this information in a credits or - "About" dialog. Returns an empty string if the - provider has no credit text. Only report credit text - when absolutely required (for example, an "advertisement - clause" related to licensing). Do not use it for - reporting general author information. - */ - virtual QString credit() const; - - /** - 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; - - /** - Method to set up the default configuration options. - - If your provider needs some configuration options, - this method allows you to establish default options. - The user can then change the configuration options - as required, and set them using configChanged(). - - You need to return a QVariantMap that has configuration - options as the keys, and the default configuration - as the values, as shown below: - \code -QVariantMap defaultConfig() const -{ - QVariantMap myConfig; - myConfig[ "firstOption" ] = QString("firstOptionValue"); - myConfig[ "secondOption" ] = true; - myConfig[ "thirdOpt" ] = 1243; - return myConfig; -} - \endcode - - \sa configChanged for how to set the configuration; - */ - virtual QVariantMap defaultConfig() const; - - /** - Method to set the configuration options. - - If your provider supports configuration options, you - will be advised of user changes to the configuration - when this method is called. - - \param config the new configuration to be used by the provider - */ - virtual void configChanged(const QVariantMap &config); + virtual ~Provider(); + + class Context; + + /** + 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(); + + /** + Deinitialisation routine + + This routine will be called just before provider destruction. + Notably, during QCA shutdown, deinit() will be called on all + providers before any of the providers are destructed. Use this + opportunity to free any resources that may be used by other + providers. + */ + virtual void deinit(); + + /** + Version number of the plugin + + The format is the same as QCA itself. Version 1.2.3 would be + represented as 0x010203. + + The default returns 0 (version 0.0.0). + */ + virtual int version() const; + + /** + Target QCA version for the provider. + + This is used to verify compatibility between the + provider and QCA. For a provider to be used, it + must supply major and minor version numbers here that are + less-than or equal to the actual QCA version (the patch + version number is ignored). This means an older + provider may be used with a newer QCA, but a newer + provider cannot be used with an older QCA. + */ + virtual int qcaVersion() const = 0; + + /** + 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(sha1)"; + return list; + } + \endcode + */ + virtual QStringList features() const = 0; + + /** + Optional credit text for the provider. + + You might display this information in a credits or + "About" dialog. Returns an empty string if the + provider has no credit text. Only report credit text + when absolutely required (for example, an "advertisement + clause" related to licensing). Do not use it for + reporting general author information. + */ + virtual QString credit() const; + + /** + 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; + + /** + Method to set up the default configuration options. + + If your provider needs some configuration options, + this method allows you to establish default options. + The user can then change the configuration options + as required, and set them using configChanged(). + + You need to return a QVariantMap that has configuration + options as the keys, and the default configuration + as the values, as shown below: + \code + QVariantMap defaultConfig() const + { + QVariantMap myConfig; + myConfig[ "firstOption" ] = QString("firstOptionValue"); + myConfig[ "secondOption" ] = true; + myConfig[ "thirdOpt" ] = 1243; + return myConfig; + } + \endcode + + \sa configChanged for how to set the configuration; + */ + virtual QVariantMap defaultConfig() const; + + /** + Method to set the configuration options. + + If your provider supports configuration options, you + will be advised of user changes to the configuration + when this method is called. + + \param config the new configuration to be used by the provider + */ + virtual void configChanged(const QVariantMap &config); }; /** @@ -923,58 +931,58 @@ */ class QCA_EXPORT Provider::Context : public QObject { - Q_OBJECT + Q_OBJECT public: - virtual ~Context(); + virtual ~Context(); - /** - The Provider associated with this Context - */ - Provider *provider() const; + /** + The Provider associated with this Context + */ + Provider *provider() const; - /** - The type of context, as passed to the constructor - */ - QString type() const; + /** + The type of context, as passed to the constructor + */ + QString type() const; - /** - Create a duplicate of this Context - */ - virtual Context *clone() const = 0; + /** + Create a duplicate of this Context + */ + virtual Context *clone() const = 0; - /** - Test if two Contexts have the same Provider + /** + Test if two Contexts have the same Provider - \param c pointer to the Context to compare to + \param c pointer to the Context to compare to - \return true if the argument and this Context - have the same provider. - */ - bool sameProvider(const Context *c) const; + \return true if the argument and this Context + have the same provider. + */ + bool sameProvider(const Context *c) const; protected: - /** - Standard constructor + /** + Standard constructor - \param parent the parent provider for this - context - \param type the name of the provider context type - */ - Context(Provider *parent, const QString &type); + \param parent the parent provider for this + context + \param type the name of the provider context type + */ + Context(Provider *parent, const QString &type); - /** - Copy constructor + /** + Copy constructor - \param from the Context to copy from - */ - Context(const Context &from); + \param from the Context to copy from + */ + Context(const Context &from); private: - // disable assignment - Context & operator=(const Context &from); + // disable assignment + Context &operator=(const Context &from); - Provider *_provider; - QString _type; + Provider *_provider; + QString _type; }; /** @@ -993,30 +1001,30 @@ */ class QCA_EXPORT BasicContext : public Provider::Context { - Q_OBJECT + Q_OBJECT public: - ~BasicContext(); + ~BasicContext(); protected: - /** - Standard constructor + /** + Standard constructor - \param parent the parent provider for this - context - \param type the name of the provider context type - */ - BasicContext(Provider *parent, const QString &type); + \param parent the parent provider for this + context + \param type the name of the provider context type + */ + BasicContext(Provider *parent, const QString &type); - /** - Copy constructor + /** + Copy constructor - \param from the Context to copy from - */ - BasicContext(const BasicContext &from); + \param from the Context to copy from + */ + BasicContext(const BasicContext &from); private: - // disable assignment - BasicContext & operator=(const BasicContext &from); + // disable assignment + BasicContext &operator=(const BasicContext &from); }; /** @@ -1036,39 +1044,39 @@ 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 MemoryRegion &a) = 0; - - /** - Complete the algorithm and return the internal state - */ - virtual MemoryRegion 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. - - \param a the data to process. - */ - MemoryRegion process(const MemoryRegion &a); + 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 MemoryRegion &a) = 0; + + /** + Complete the algorithm and return the internal state + */ + virtual MemoryRegion 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. + + \param a the data to process. + */ + MemoryRegion process(const MemoryRegion &a); }; /** @@ -1092,53 +1100,53 @@ class QCA_EXPORT Filter { public: - virtual ~Filter(); - - /** - Reset the internal state - */ - virtual void clear() = 0; - - /** - Process more data, returning the corresponding - filtered version of the data. - - \param a the array containing data to process - */ - virtual MemoryRegion update(const MemoryRegion &a) = 0; - - /** - Complete the algorithm, returning any - additional results. - */ - virtual MemoryRegion final() = 0; - - /** - Test if an update() or final() call succeeded. - - \return true if the previous call succeeded - */ - virtual bool ok() const = 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. - - \param a the data to process in this step - */ - MemoryRegion process(const MemoryRegion &a); + virtual ~Filter(); + + /** + Reset the internal state + */ + virtual void clear() = 0; + + /** + Process more data, returning the corresponding + filtered version of the data. + + \param a the array containing data to process + */ + virtual MemoryRegion update(const MemoryRegion &a) = 0; + + /** + Complete the algorithm, returning any + additional results. + */ + virtual MemoryRegion final() = 0; + + /** + Test if an update() or final() call succeeded. + + \return true if the previous call succeeded + */ + virtual bool ok() const = 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. + + \param a the data to process in this step + */ + MemoryRegion process(const MemoryRegion &a); }; /** \class Algorithm qca_core.h QtCrypto - General superclass for an algorithm. + General superclass for an algorithm. This is a fairly abstract class, mainly used for implementing the backend "provider" interface. @@ -1148,94 +1156,94 @@ class QCA_EXPORT Algorithm { public: - /** - Standard copy constructor + /** + Standard copy constructor - \param from the Algorithm to copy from - */ - Algorithm(const Algorithm &from); + \param from the Algorithm to copy from + */ + Algorithm(const Algorithm &from); - virtual ~Algorithm(); + virtual ~Algorithm(); - /** - Assignment operator + /** + Assignment operator - \param from the Algorithm to copy state from - */ - Algorithm & operator=(const Algorithm &from); + \param from the Algorithm to copy state from + */ + Algorithm &operator=(const Algorithm &from); - /** - The name of the algorithm type. - */ - QString type() const; + /** + The name of the algorithm type. + */ + QString type() const; - /** - The name of the provider + /** + 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; + Each algorithm is implemented by a provider. This + allows you to figure out which provider is associated + */ + Provider *provider() const; - // Note: The next five functions are not public! + // Note: The next five functions are not public! - /** - \internal + /** + \internal - The context associated with this algorithm - */ - Provider::Context *context(); + The context associated with this algorithm + */ + Provider::Context *context(); - /** - \internal + /** + \internal - The context associated with this algorithm - */ - const Provider::Context *context() const; + The context associated with this algorithm + */ + const Provider::Context *context() const; - /** - \internal + /** + \internal - Set the Provider for this algorithm + Set the Provider for this algorithm - \param c the context for the Provider to use - */ - void change(Provider::Context *c); + \param c the context for the Provider to use + */ + void change(Provider::Context *c); - /** - \internal + /** + \internal - \overload + \overload - \param type the name of the algorithm to use - \param provider the name of the preferred provider - */ - void change(const QString &type, const QString &provider); + \param type the name of the algorithm to use + \param provider the name of the preferred provider + */ + void change(const QString &type, const QString &provider); - /** - \internal + /** + \internal - Take the Provider from this algorithm - */ - Provider::Context *takeContext(); + Take the Provider from this algorithm + */ + Provider::Context *takeContext(); protected: - /** - Constructor for empty algorithm - */ - Algorithm(); + /** + Constructor for empty algorithm + */ + Algorithm(); - /** - Constructor of a particular algorithm. + /** + Constructor of a particular algorithm. - \param type the algorithm to construct - \param provider the name of a particular Provider - */ - Algorithm(const QString &type, const QString &provider); + \param type the algorithm to construct + \param provider the name of a particular Provider + */ + Algorithm(const QString &type, const QString &provider); private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** @@ -1248,40 +1256,40 @@ class QCA_EXPORT SymmetricKey : public SecureArray { public: - /** - Construct an empty (zero length) key - */ - SymmetricKey(); + /** + Construct an empty (zero length) key + */ + SymmetricKey(); - /** - Construct an key of specified size, with random contents + /** + Construct an key of specified size, with random contents - This is intended to be used as a random session key. + This is intended to be used as a random session key. - \param size the number of bytes for the key - */ - SymmetricKey(int size); + \param size the number of bytes for the key + */ + SymmetricKey(int size); - /** - Construct a key from a provided byte array + /** + Construct a key from a provided byte array - \param a the byte array to copy - */ - SymmetricKey(const SecureArray &a); + \param a the byte array to copy + */ + SymmetricKey(const SecureArray &a); - /** - Construct a key from a provided byte array + /** + Construct a key from a provided byte array - \param a the byte array to copy - */ - SymmetricKey(const QByteArray &a); + \param a the byte array to copy + */ + SymmetricKey(const QByteArray &a); - /** - Test for weak DES keys + /** + Test for weak DES keys - \return true if the key is a weak key for DES - */ - bool isWeakDESKey(); + \return true if the key is a weak key for DES + */ + bool isWeakDESKey(); }; /** @@ -1294,31 +1302,31 @@ class QCA_EXPORT InitializationVector : public SecureArray { public: - /** - Construct an empty (zero length) initisation vector - */ - InitializationVector(); + /** + Construct an empty (zero length) initisation vector + */ + InitializationVector(); - /** - Construct an initialisation vector of the specified size + /** + Construct an initialisation vector of the specified size - \param size the length of the initialisation vector, in bytes - */ - InitializationVector(int size); + \param size the length of the initialisation vector, in bytes + */ + InitializationVector(int size); - /** - Construct an initialisation vector from a provided byte array + /** + Construct an initialisation vector from a provided byte array - \param a the byte array to copy - */ - InitializationVector(const SecureArray &a); + \param a the byte array to copy + */ + InitializationVector(const SecureArray &a); - /** - Construct an initialisation vector from a provided byte array + /** + Construct an initialisation vector from a provided byte array - \param a the byte array to copy - */ - InitializationVector(const QByteArray &a); + \param a the byte array to copy + */ + InitializationVector(const QByteArray &a); }; /** @@ -1331,31 +1339,31 @@ class QCA_EXPORT AuthTag : public SecureArray { public: - /** - Construct an empty authentication tag - */ - AuthTag(); + /** + Construct an empty authentication tag + */ + AuthTag(); - /** - Construct an empty authentication tag of the specified size + /** + Construct an empty authentication tag of the specified size - \param size the length of the authentication tag, in bytes - */ - AuthTag(int size); + \param size the length of the authentication tag, in bytes + */ + AuthTag(int size); - /** - Construct an authentication tag from a provided byte array + /** + Construct an authentication tag from a provided byte array - \param a the byte array to copy - */ - AuthTag(const SecureArray &a); + \param a the byte array to copy + */ + AuthTag(const SecureArray &a); - /** - Construct an authentication tag from a provided byte array + /** + Construct an authentication tag from a provided byte array - \param a the byte array to copy - */ - AuthTag(const QByteArray &a); + \param a the byte array to copy + */ + AuthTag(const QByteArray &a); }; /** @@ -1375,169 +1383,166 @@ class QCA_EXPORT Event { public: - /** - %Type of event - - \sa type() - */ - enum Type - { - Password, ///< Asking for a password, PIN or passphrase. - Token ///< Asking for a token - }; - - /** - %Source of the event - - Events are associated with access to a KeyStore, or access to - a file (or bytearray/stream or equivalent). This tells you the - type of source that caused the Event. - - \sa source() - \sa fileName() for the name, if source is Event::Data - \sa keyStoreInfo() and keyStoreEntry() for the keystore and entry, - if the source is Event::KeyStore - */ - enum Source - { - KeyStore, ///< KeyStore generated the event - Data ///< File or bytearray generated the event - }; - - /** - password variation - - If the Type of Event is Password, PasswordStyle tells you whether - it is a PIN, passphrase or password. - - \sa passwordStyle() - */ - enum PasswordStyle - { - StylePassword, ///< User should be prompted for a "Password" - StylePassphrase, ///< User should be prompted for a "Passphrase" - StylePIN ///< User should be prompted for a "PIN" - }; - - /** - Constructor - */ - Event(); - - /** - Copy constructor - - \param from the Event to copy from - */ - Event(const Event &from); - - /** - Destructor - */ - ~Event(); - - /** - Assignment operator - - \param from the Event to copy from - */ - Event & operator=(const Event &from); - - /** - test if this event has been setup correctly - */ - bool isNull() const; - - /** - the Type of this event - */ - Type type() const; - - /** - the Source of this event - */ - Source source() const; - - /** - the style of password required. - - This is not meaningful unless the Type is Event::Password. - - \sa PasswordStyle - */ - PasswordStyle passwordStyle() const; - - /** - The info of the KeyStore associated with this event - - This is not meaningful unless the Source is KeyStore. - */ - KeyStoreInfo keyStoreInfo() const; - - /** - The KeyStoreEntry associated with this event - - This is not meaningful unless the Source is KeyStore. - */ - KeyStoreEntry keyStoreEntry() const; - - /** - Name or other identifier for the file or byte array - associated with this event. - - This is not meaningful unless the Source is Data. - */ - QString fileName() const; - - /** - opaque data - */ - void *ptr() const; - - /** - Set the values for this Event - - This creates a Password type event, for a keystore. - - \param pstyle the style of information required (e.g. PIN, - password or passphrase) - \param keyStoreInfo info about the keystore that the information - is required for - \param keyStoreEntry the entry in the keystore that the - information is required for - \param ptr opaque data - */ - void setPasswordKeyStore(PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); - - /** - Set the values for this Event - - This creates a Password type event, for a file. - - \param pstyle the style of information required (e.g. PIN, - password or passphrase) - \param fileName the name of the file (or other identifier) that - the information is required for - \param ptr opaque data - */ - void setPasswordData(PasswordStyle pstyle, const QString &fileName, void *ptr); + /** + %Type of event + + \sa type() + */ + enum Type { + Password, ///< Asking for a password, PIN or passphrase. + Token ///< Asking for a token + }; + + /** + %Source of the event + + Events are associated with access to a KeyStore, or access to + a file (or bytearray/stream or equivalent). This tells you the + type of source that caused the Event. + + \sa source() + \sa fileName() for the name, if source is Event::Data + \sa keyStoreInfo() and keyStoreEntry() for the keystore and entry, + if the source is Event::KeyStore + */ + enum Source { + KeyStore, ///< KeyStore generated the event + Data ///< File or bytearray generated the event + }; + + /** + password variation + + If the Type of Event is Password, PasswordStyle tells you whether + it is a PIN, passphrase or password. + + \sa passwordStyle() + */ + enum PasswordStyle { + StylePassword, ///< User should be prompted for a "Password" + StylePassphrase, ///< User should be prompted for a "Passphrase" + StylePIN ///< User should be prompted for a "PIN" + }; + + /** + Constructor + */ + Event(); + + /** + Copy constructor + + \param from the Event to copy from + */ + Event(const Event &from); + + /** + Destructor + */ + ~Event(); + + /** + Assignment operator + + \param from the Event to copy from + */ + Event &operator=(const Event &from); + + /** + test if this event has been setup correctly + */ + bool isNull() const; + + /** + the Type of this event + */ + Type type() const; + + /** + the Source of this event + */ + Source source() const; + + /** + the style of password required. + + This is not meaningful unless the Type is Event::Password. + + \sa PasswordStyle + */ + PasswordStyle passwordStyle() const; + + /** + The info of the KeyStore associated with this event + + This is not meaningful unless the Source is KeyStore. + */ + KeyStoreInfo keyStoreInfo() const; + + /** + The KeyStoreEntry associated with this event + + This is not meaningful unless the Source is KeyStore. + */ + KeyStoreEntry keyStoreEntry() const; + + /** + Name or other identifier for the file or byte array + associated with this event. + + This is not meaningful unless the Source is Data. + */ + QString fileName() const; + + /** + opaque data + */ + void *ptr() const; + + /** + Set the values for this Event + + This creates a Password type event, for a keystore. + + \param pstyle the style of information required (e.g. PIN, + password or passphrase) + \param keyStoreInfo info about the keystore that the information + is required for + \param keyStoreEntry the entry in the keystore that the + information is required for + \param ptr opaque data + */ + void setPasswordKeyStore(PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); + + /** + Set the values for this Event + + This creates a Password type event, for a file. + + \param pstyle the style of information required (e.g. PIN, + password or passphrase) + \param fileName the name of the file (or other identifier) that + the information is required for + \param ptr opaque data + */ + void setPasswordData(PasswordStyle pstyle, const QString &fileName, void *ptr); - /** - Set the values for this Event + /** + Set the values for this Event - This creates a Token type event. + This creates a Token type event. - \param keyStoreInfo info about the keystore that the token is - required for - \param keyStoreEntry the entry in the keystore that the token is - required for - \param ptr opaque data - */ - void setToken(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); + \param keyStoreInfo info about the keystore that the token is + required for + \param keyStoreEntry the entry in the keystore that the token is + required for + \param ptr opaque data + */ + void setToken(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** @@ -1559,75 +1564,75 @@ */ class QCA_EXPORT EventHandler : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Constructor + /** + Constructor - \param parent the parent object for this object - */ - EventHandler(QObject *parent = 0); - ~EventHandler(); + \param parent the parent object for this object + */ + EventHandler(QObject *parent = 0); + ~EventHandler(); - /** - mandatory function to call after connecting the - signal to a slot in your application specific password - / passphrase / PIN or token handler - */ - void start(); + /** + mandatory function to call after connecting the + signal to a slot in your application specific password + / passphrase / PIN or token handler + */ + void start(); - /** - function to call to return the user provided - password, passphrase or PIN. + /** + function to call to return the user provided + password, passphrase or PIN. - \param id the id corresponding to the password request - \param password the user-provided password, passphrase or PIN. + \param id the id corresponding to the password request + \param password the user-provided password, passphrase or PIN. - \note the id parameter is the same as that provided in the - eventReady() signal. - */ - void submitPassword(int id, const SecureArray &password); + \note the id parameter is the same as that provided in the + eventReady() signal. + */ + void submitPassword(int id, const SecureArray &password); - /** - function to call to indicate that the token has been inserted - by the user. + /** + function to call to indicate that the token has been inserted + by the user. - \param id the id corresponding to the password request + \param id the id corresponding to the password request - \note the id parameter is the same as that provided in the - eventReady() signal. - */ - void tokenOkay(int id); + \note the id parameter is the same as that provided in the + eventReady() signal. + */ + void tokenOkay(int id); - /** - function to call to indicate that the user declined to - provide a password, passphrase, PIN or token. + /** + function to call to indicate that the user declined to + provide a password, passphrase, PIN or token. - \param id the id corresponding to the password request + \param id the id corresponding to the password request - \note the id parameter is the same as that provided in the - eventReady() signal. - */ - void reject(int id); + \note the id parameter is the same as that provided in the + eventReady() signal. + */ + void reject(int id); Q_SIGNALS: - /** - signal emitted when an Event requires attention. + /** + signal emitted when an Event requires attention. - You typically need to connect this signal to - a compatible slot in your callback handler + You typically need to connect this signal to + a compatible slot in your callback handler - \param id the identification number for the event - \param context information about the type of response required - */ - void eventReady(int id, const QCA::Event &context); + \param id the identification number for the event + \param context information about the type of response required + */ + void eventReady(int id, const QCA::Event &context); private: - Q_DISABLE_COPY(EventHandler) + Q_DISABLE_COPY(EventHandler) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -1641,85 +1646,85 @@ */ class QCA_EXPORT PasswordAsker : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Construct a new asker - - \param parent the parent object for this QObject - */ - PasswordAsker(QObject *parent = 0); - ~PasswordAsker(); - - /** - queue a password / passphrase request associated with a key store - - \param pstyle the type of information required (e.g. PIN, - passphrase or password) - \param keyStoreInfo info of the key store that the information is - required for - \param keyStoreEntry the item in the key store that the - information is required for (if applicable) - \param ptr opaque data - */ - void ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); - - /** - queue a password / passphrase request associated with a file - - \param pstyle the type of information required (e.g. PIN, - passphrase or password) - \param fileName the name of the file that the information is - required for - \param ptr opaque data - */ - void ask(Event::PasswordStyle pstyle, const QString &fileName, void *ptr); - - /** - Cancel the pending password / passphrase request - */ - void cancel(); - - /** - Block until the password / passphrase request is - completed - - You can use the responseReady signal instead of - blocking, if appropriate. - */ - void waitForResponse(); - - /** - Determine whether the password / passphrase was accepted or not - - In this context, returning true is indicative of the user clicking - "Ok" or equivalent; and returning false indicates that either the - user clicked "Cancel" or equivalent, or that the cancel() function - was called, or that the request is still pending. - */ - bool accepted() const; - - /** - The password / passphrase / PIN provided by the user in response - to the asker request. This may be empty. - */ - SecureArray password() const; + /** + Construct a new asker + + \param parent the parent object for this QObject + */ + PasswordAsker(QObject *parent = 0); + ~PasswordAsker(); + + /** + queue a password / passphrase request associated with a key store + + \param pstyle the type of information required (e.g. PIN, + passphrase or password) + \param keyStoreInfo info of the key store that the information is + required for + \param keyStoreEntry the item in the key store that the + information is required for (if applicable) + \param ptr opaque data + */ + void ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); + + /** + queue a password / passphrase request associated with a file + + \param pstyle the type of information required (e.g. PIN, + passphrase or password) + \param fileName the name of the file that the information is + required for + \param ptr opaque data + */ + void ask(Event::PasswordStyle pstyle, const QString &fileName, void *ptr); + + /** + Cancel the pending password / passphrase request + */ + void cancel(); + + /** + Block until the password / passphrase request is + completed + + You can use the responseReady signal instead of + blocking, if appropriate. + */ + void waitForResponse(); + + /** + Determine whether the password / passphrase was accepted or not + + In this context, returning true is indicative of the user clicking + "Ok" or equivalent; and returning false indicates that either the + user clicked "Cancel" or equivalent, or that the cancel() function + was called, or that the request is still pending. + */ + bool accepted() const; + + /** + The password / passphrase / PIN provided by the user in response + to the asker request. This may be empty. + */ + SecureArray password() const; Q_SIGNALS: - /** - Emitted when the asker process has been completed. + /** + Emitted when the asker process has been completed. - You should check whether the user accepted() the response - prior to relying on the password(). - */ - void responseReady(); + You should check whether the user accepted() the response + prior to relying on the password(). + */ + void responseReady(); private: - Q_DISABLE_COPY(PasswordAsker) + Q_DISABLE_COPY(PasswordAsker) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -1733,62 +1738,62 @@ */ class QCA_EXPORT TokenAsker : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Construct a new asker - - \param parent the parent object for this QObject - */ - TokenAsker(QObject *parent = 0); - ~TokenAsker(); - - /** - queue a token request associated with a key store - - \param keyStoreInfo info of the key store that the information is - required for - \param keyStoreEntry the item in the key store that the - information is required for (if applicable) - \param ptr opaque data - */ - void ask(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); - - /** - Cancel the pending password / passphrase request - */ - void cancel(); - - /** - Block until the token request is completed - - You can use the responseReady signal instead of - blocking, if appropriate. - */ - void waitForResponse(); - - /** - Test if the token request was accepted or not. - - \return true if the token request was accepted - */ - bool accepted() const; + /** + Construct a new asker + + \param parent the parent object for this QObject + */ + TokenAsker(QObject *parent = 0); + ~TokenAsker(); + + /** + queue a token request associated with a key store + + \param keyStoreInfo info of the key store that the information is + required for + \param keyStoreEntry the item in the key store that the + information is required for (if applicable) + \param ptr opaque data + */ + void ask(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr); + + /** + Cancel the pending password / passphrase request + */ + void cancel(); + + /** + Block until the token request is completed + + You can use the responseReady signal instead of + blocking, if appropriate. + */ + void waitForResponse(); + + /** + Test if the token request was accepted or not. + + \return true if the token request was accepted + */ + bool accepted() const; Q_SIGNALS: - /** - Emitted when the asker process has been completed. + /** + Emitted when the asker process has been completed. - You should check whether the user accepted() the response - prior to relying on token being present. - */ - void responseReady(); + You should check whether the user accepted() the response + prior to relying on token being present. + */ + void responseReady(); private: - Q_DISABLE_COPY(TokenAsker) + Q_DISABLE_COPY(TokenAsker) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; } diff --git a/include/QtCrypto/qca_export.h b/include/QtCrypto/qca_export.h --- a/include/QtCrypto/qca_export.h +++ b/include/QtCrypto/qca_export.h @@ -22,7 +22,7 @@ /** \file qca_export.h - Preprocessor magic to allow export of library symbols. + Preprocessor magic to allow export of library symbols. This is strictly internal. diff --git a/include/QtCrypto/qca_keystore.h b/include/QtCrypto/qca_keystore.h --- a/include/QtCrypto/qca_keystore.h +++ b/include/QtCrypto/qca_keystore.h @@ -36,7 +36,8 @@ #include "qca_core.h" #include "qca_cert.h" -namespace QCA { +namespace QCA +{ class KeyStoreTracker; class KeyStoreManagerPrivate; @@ -140,192 +141,191 @@ class QCA_EXPORT KeyStoreEntry : public Algorithm { public: - /** - The type of entry in the KeyStore - */ - enum Type - { - TypeKeyBundle, - TypeCertificate, - TypeCRL, - TypePGPSecretKey, - TypePGPPublicKey - }; - - /** - Create an empty KeyStoreEntry - */ - KeyStoreEntry(); - - /** - Create a passive KeyStoreEntry based on a serialized - string - - \param serialized the string containing the keystore entry information - - \sa fromString - */ - KeyStoreEntry(const QString &serialized); - - /** - Standard copy constructor - - \param from the source entry - */ - KeyStoreEntry(const KeyStoreEntry &from); - - ~KeyStoreEntry(); - - /** - Standard assignment operator - - \param from the source entry - */ - KeyStoreEntry & operator=(const KeyStoreEntry &from); - - /** - Test if this key is empty (null) - */ - bool isNull() const; - - /** - Test if the key is available for use. - - A key is considered available if the key's private - content is present. - - \sa ensureAvailable - \sa isAccessible - */ - bool isAvailable() const; - - /** - Test if the key is currently accessible. - - This means that the private key part can be used - at this time. For a smartcard, this means that all - required operations (e.g. login / PIN entry) are - completed. - - If isAccessible() is true, then the key - is necessarily available (i.e. isAvailable() is - also true). - - \sa ensureAccessible - \sa isAvailable - */ - bool isAccessible() const; - - /** - Determine the type of key stored in this object - */ - Type type() const; - - /** - The name associated with the key stored in this object - */ - QString name() const; - - /** - The ID associated with the key stored in this object. - */ - QString id() const; - - /** - The name of the KeyStore for this key object - */ - QString storeName() const; - - /** - The id of the KeyStore for this key object - - \sa KeyStore::id() - */ - QString storeId() const; - - /** - Serialize into a string for use as a passive entry - */ - QString toString() const; - - /** - Load a passive entry by using a serialized string - as input - - \param serialized the string containing the keystore entry information - - \return the newly created KeyStoreEntry - */ - static KeyStoreEntry fromString(const QString &serialized); - - /** - If a KeyBundle is stored in this object, return that - bundle. - */ - KeyBundle keyBundle() const; - - /** - If a Certificate is stored in this object, return that - certificate. - */ - Certificate certificate() const; - - /** - If a CRL is stored in this object, return the value - of the CRL - */ - CRL crl() const; - - /** - If the key stored in this object is a private - PGP key, return the contents of that key. - */ - PGPKey pgpSecretKey() const; - - /** - If the key stored in this object is either an - public or private PGP key, extract the public key - part of that PGP key. - */ - PGPKey pgpPublicKey() const; - - /** - Returns true if the entry is available, otherwise false. - - Available means that any private content for this entry is - present and ready for use. In the case of a smart card, this - will ensure the card is inserted, and may invoke a token - prompt. - - Calling this function on an already available entry may cause - the entry to be refreshed. - - \sa isAvailable - \sa ensureAccess - - \note This function is blocking. - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - bool ensureAvailable(); - - /** - Like ensureAvailable, but will also ensure - that the PIN is provided if needed. - - \sa isAccessible - \sa ensureAvailable - - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - bool ensureAccess(); + /** + The type of entry in the KeyStore + */ + enum Type { + TypeKeyBundle, + TypeCertificate, + TypeCRL, + TypePGPSecretKey, + TypePGPPublicKey + }; + + /** + Create an empty KeyStoreEntry + */ + KeyStoreEntry(); + + /** + Create a passive KeyStoreEntry based on a serialized + string + + \param serialized the string containing the keystore entry information + + \sa fromString + */ + KeyStoreEntry(const QString &serialized); + + /** + Standard copy constructor + + \param from the source entry + */ + KeyStoreEntry(const KeyStoreEntry &from); + + ~KeyStoreEntry(); + + /** + Standard assignment operator + + \param from the source entry + */ + KeyStoreEntry &operator=(const KeyStoreEntry &from); + + /** + Test if this key is empty (null) + */ + bool isNull() const; + + /** + Test if the key is available for use. + + A key is considered available if the key's private + content is present. + + \sa ensureAvailable + \sa isAccessible + */ + bool isAvailable() const; + + /** + Test if the key is currently accessible. + + This means that the private key part can be used + at this time. For a smartcard, this means that all + required operations (e.g. login / PIN entry) are + completed. + + If isAccessible() is true, then the key + is necessarily available (i.e. isAvailable() is + also true). + + \sa ensureAccessible + \sa isAvailable + */ + bool isAccessible() const; + + /** + Determine the type of key stored in this object + */ + Type type() const; + + /** + The name associated with the key stored in this object + */ + QString name() const; + + /** + The ID associated with the key stored in this object. + */ + QString id() const; + + /** + The name of the KeyStore for this key object + */ + QString storeName() const; + + /** + The id of the KeyStore for this key object + + \sa KeyStore::id() + */ + QString storeId() const; + + /** + Serialize into a string for use as a passive entry + */ + QString toString() const; + + /** + Load a passive entry by using a serialized string + as input + + \param serialized the string containing the keystore entry information + + \return the newly created KeyStoreEntry + */ + static KeyStoreEntry fromString(const QString &serialized); + + /** + If a KeyBundle is stored in this object, return that + bundle. + */ + KeyBundle keyBundle() const; + + /** + If a Certificate is stored in this object, return that + certificate. + */ + Certificate certificate() const; + + /** + If a CRL is stored in this object, return the value + of the CRL + */ + CRL crl() const; + + /** + If the key stored in this object is a private + PGP key, return the contents of that key. + */ + PGPKey pgpSecretKey() const; + + /** + If the key stored in this object is either an + public or private PGP key, extract the public key + part of that PGP key. + */ + PGPKey pgpPublicKey() const; + + /** + Returns true if the entry is available, otherwise false. + + Available means that any private content for this entry is + present and ready for use. In the case of a smart card, this + will ensure the card is inserted, and may invoke a token + prompt. + + Calling this function on an already available entry may cause + the entry to be refreshed. + + \sa isAvailable + \sa ensureAccess + + \note This function is blocking. + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + bool ensureAvailable(); + + /** + Like ensureAvailable, but will also ensure + that the PIN is provided if needed. + + \sa isAccessible + \sa ensureAvailable + + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + bool ensureAccess(); private: - class Private; - Private *d; + class Private; + Private *d; - friend class KeyStoreTracker; + friend class KeyStoreTracker; }; /** @@ -335,60 +335,60 @@ Some KeyStore types have the concept of an entry that can be available only part of the time (for example, a smart card that - can be removed). This class allows you to identify when a + can be removed). This class allows you to identify when a KeyStoreEntry becomes available / unavailable. \note You can also monitor availability of a whole KeyStore, using KeyStoreManager::keyStoreAvailable() signal, and - the KeyStore::unavailable() signal. + the KeyStore::unavailable() signal. - \sa KeyStore for more discussion on availability of + \sa KeyStore for more discussion on availability of keys and related objects. \ingroup UserAPI */ class QCA_EXPORT KeyStoreEntryWatcher : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor. + /** + Standard constructor. - This creates an object that monitors the specified KeyStore entry, - emitting available() and unavailable() as the entry becomes available - and unavailable respectively. + This creates an object that monitors the specified KeyStore entry, + emitting available() and unavailable() as the entry becomes available + and unavailable respectively. - \param e the KeyStoreEntry to monitor - \param parent the parent object for this object - */ - explicit KeyStoreEntryWatcher(const KeyStoreEntry &e, QObject *parent = 0); + \param e the KeyStoreEntry to monitor + \param parent the parent object for this object + */ + explicit KeyStoreEntryWatcher(const KeyStoreEntry &e, QObject *parent = 0); - ~KeyStoreEntryWatcher(); + ~KeyStoreEntryWatcher(); - /** - The KeyStoreEntry that is being monitored - */ - KeyStoreEntry entry() const; + /** + The KeyStoreEntry that is being monitored + */ + KeyStoreEntry entry() const; Q_SIGNALS: - /** - This signal is emitted when the entry that is being monitored - becomes available. - */ - void available(); - - /** - This signal is emitted when the entry that is being monitored - becomes unavailble. - */ - void unavailable(); + /** + This signal is emitted when the entry that is being monitored + becomes available. + */ + void available(); + + /** + This signal is emitted when the entry that is being monitored + becomes unavailble. + */ + void unavailable(); private: - Q_DISABLE_COPY(KeyStoreEntryWatcher) + Q_DISABLE_COPY(KeyStoreEntryWatcher) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -415,190 +415,189 @@ */ class QCA_EXPORT KeyStore : public QObject, public Algorithm { - Q_OBJECT + Q_OBJECT public: - /** - The type of keystore - */ - enum Type - { - System, ///< objects such as root certificates - User, ///< objects such as Apple Keychain, KDE Wallet - Application, ///< for caching accepted self-signed certificates - SmartCard, ///< for smartcards - PGPKeyring ///< for a PGP keyring - }; - - /** - Obtain a specific KeyStore - - \param id the identification for the key store - \param keyStoreManager the parent manager for this keystore - */ - KeyStore(const QString &id, KeyStoreManager *keyStoreManager); - - ~KeyStore(); - - /** - Check if this KeyStore is valid - - \return true if the KeyStore is valid - */ - bool isValid() const; - - /** - The KeyStore Type - */ - Type type() const; - - /** - The name associated with the KeyStore - */ - QString name() const; - - /** - The ID associated with the KeyStore - */ - QString id() const; - - /** - Test if the KeyStore is writeable or not - - \return true if the KeyStore is read-only - */ - bool isReadOnly() const; - - /** - Turns on asynchronous mode for this KeyStore instance. - - Normally, entryList() and writeEntry() are blocking - calls. However, if startAsynchronousMode() is called, - then these functions will return immediately. entryList() - will return with the latest known entries, or an empty - list if none are known yet (in this mode, updated() will - be emitted once the initial entries are known, even if the - store has not actually been altered). writeEntry() will - always return an empty string, and the entryWritten() - signal indicates the result of a write. - */ - void startAsynchronousMode(); - - /** - A list of the KeyStoreEntry objects in this store - - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler - (this is not a concern if asynchronous mode is enabled). - - \sa startAsynchronousMode - */ - QList entryList() const; - - /** - test if the KeyStore holds trusted certificates (and CRLs) - */ - bool holdsTrustedCertificates() const; - - /** - test if the KeyStore holds identities (eg KeyBundle or PGPSecretKey) - */ - bool holdsIdentities() const; - - /** - test if the KeyStore holds PGPPublicKey objects - */ - bool holdsPGPPublicKeys() const; - - /** - Add a entry to the KeyStore - - Returns the entryId of the written entry or an empty - string on failure. - - \param kb the KeyBundle to add to the KeyStore - - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler - (this is not a concern if asynchronous mode is enabled). + /** + The type of keystore + */ + enum Type { + System, ///< objects such as root certificates + User, ///< objects such as Apple Keychain, KDE Wallet + Application, ///< for caching accepted self-signed certificates + SmartCard, ///< for smartcards + PGPKeyring ///< for a PGP keyring + }; + + /** + Obtain a specific KeyStore + + \param id the identification for the key store + \param keyStoreManager the parent manager for this keystore + */ + KeyStore(const QString &id, KeyStoreManager *keyStoreManager); + + ~KeyStore(); + + /** + Check if this KeyStore is valid + + \return true if the KeyStore is valid + */ + bool isValid() const; + + /** + The KeyStore Type + */ + Type type() const; + + /** + The name associated with the KeyStore + */ + QString name() const; + + /** + The ID associated with the KeyStore + */ + QString id() const; + + /** + Test if the KeyStore is writeable or not + + \return true if the KeyStore is read-only + */ + bool isReadOnly() const; + + /** + Turns on asynchronous mode for this KeyStore instance. + + Normally, entryList() and writeEntry() are blocking + calls. However, if startAsynchronousMode() is called, + then these functions will return immediately. entryList() + will return with the latest known entries, or an empty + list if none are known yet (in this mode, updated() will + be emitted once the initial entries are known, even if the + store has not actually been altered). writeEntry() will + always return an empty string, and the entryWritten() + signal indicates the result of a write. + */ + void startAsynchronousMode(); + + /** + A list of the KeyStoreEntry objects in this store + + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler + (this is not a concern if asynchronous mode is enabled). + + \sa startAsynchronousMode + */ + QList entryList() const; + + /** + test if the KeyStore holds trusted certificates (and CRLs) + */ + bool holdsTrustedCertificates() const; + + /** + test if the KeyStore holds identities (eg KeyBundle or PGPSecretKey) + */ + bool holdsIdentities() const; + + /** + test if the KeyStore holds PGPPublicKey objects + */ + bool holdsPGPPublicKeys() const; + + /** + Add a entry to the KeyStore + + Returns the entryId of the written entry or an empty + string on failure. + + \param kb the KeyBundle to add to the KeyStore + + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler + (this is not a concern if asynchronous mode is enabled). - \sa startAsynchronousMode - */ - QString writeEntry(const KeyBundle &kb); + \sa startAsynchronousMode + */ + QString writeEntry(const KeyBundle &kb); - /** - \overload + /** + \overload - \param cert the Certificate to add to the KeyStore - */ - QString writeEntry(const Certificate &cert); + \param cert the Certificate to add to the KeyStore + */ + QString writeEntry(const Certificate &cert); - /** - \overload + /** + \overload - \param crl the CRL to add to the KeyStore - */ - QString writeEntry(const CRL &crl); + \param crl the CRL to add to the KeyStore + */ + QString writeEntry(const CRL &crl); - /** - \overload + /** + \overload - \param key the PGPKey to add to the KeyStore + \param key the PGPKey to add to the KeyStore - \return a ref to the key in the keyring - */ - QString writeEntry(const PGPKey &key); + \return a ref to the key in the keyring + */ + QString writeEntry(const PGPKey &key); - /** - Delete the a specified KeyStoreEntry from this KeyStore + /** + Delete the a specified KeyStoreEntry from this KeyStore - \param id the ID for the entry to be deleted + \param id the ID for the entry to be deleted - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler - (this is not a concern if asynchronous mode is enabled). + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler + (this is not a concern if asynchronous mode is enabled). - \sa startAsynchronousMode - */ - bool removeEntry(const QString &id); + \sa startAsynchronousMode + */ + bool removeEntry(const QString &id); Q_SIGNALS: - /** - Emitted when the KeyStore is changed + /** + Emitted when the KeyStore is changed - This occurs if entries are added, removed, or changed in this - KeyStore, including changes in entry availability. - */ - void updated(); + This occurs if entries are added, removed, or changed in this + KeyStore, including changes in entry availability. + */ + void updated(); - /** - Emitted when the KeyStore becomes unavailable - */ - void unavailable(); + /** + Emitted when the KeyStore becomes unavailable + */ + void unavailable(); - /** - Emitted when an entry has been written, in asynchronous - mode. + /** + Emitted when an entry has been written, in asynchronous + mode. - \param entryId is the newly written entry id on success, - or an empty string if the write failed. - */ - void entryWritten(const QString &entryId); + \param entryId is the newly written entry id on success, + or an empty string if the write failed. + */ + void entryWritten(const QString &entryId); - /** - Emitted when an entry has been removed, in asynchronous - mode. + /** + Emitted when an entry has been removed, in asynchronous + mode. - \param success indicates if the removal succeeded (true) or not (false). - */ - void entryRemoved(bool success); + \param success indicates if the removal succeeded (true) or not (false). + */ + void entryRemoved(bool success); private: - Q_DISABLE_COPY(KeyStore) + Q_DISABLE_COPY(KeyStore) - friend class KeyStorePrivate; - KeyStorePrivate *d; + friend class KeyStorePrivate; + KeyStorePrivate *d; - friend class KeyStoreManagerPrivate; + friend class KeyStoreManagerPrivate; }; /** @@ -611,9 +610,9 @@ to describe the key store source of the Event. Each KeyStoreInfo represents a single KeyStore, and describes - the type of store (e.g. smartcard or PGP keyring - see + the type of store (e.g. smartcard or PGP keyring - see KeyStore::Type), and a couple of names. The id() of a KeyStore - is used to reference it, and is typically of the form + is used to reference it, and is typically of the form "qca-mystorename". The name() of a KeyStore is used to describe it (i.e. this is the "pretty" name to show the user), and is typically of the form "My Store Name". @@ -623,71 +622,71 @@ class QCA_EXPORT KeyStoreInfo { public: - /** - Constructor. + /** + Constructor. - \note This form of constructor for KeyStoreInfo - produces an object that does not describe any - KeyStore, and isNull() will return true. - */ - KeyStoreInfo(); + \note This form of constructor for KeyStoreInfo + produces an object that does not describe any + KeyStore, and isNull() will return true. + */ + KeyStoreInfo(); - /** - Standard constructor. + /** + Standard constructor. - This builds a KeyStoreInfo object that descibes a - KeyStore. + This builds a KeyStoreInfo object that descibes a + KeyStore. - \param type the type of KeyStore - \param id the identification of the KeyStore - \param name the descriptive name of the KeyStore - */ - KeyStoreInfo(KeyStore::Type type, const QString &id, const QString &name); + \param type the type of KeyStore + \param id the identification of the KeyStore + \param name the descriptive name of the KeyStore + */ + KeyStoreInfo(KeyStore::Type type, const QString &id, const QString &name); - /** - Copy constructor. + /** + Copy constructor. - \param from the KeyStoreInfo to copy from - */ - KeyStoreInfo(const KeyStoreInfo &from); + \param from the KeyStoreInfo to copy from + */ + KeyStoreInfo(const KeyStoreInfo &from); - ~KeyStoreInfo(); + ~KeyStoreInfo(); - /** - Assignment operator. + /** + Assignment operator. - \param from the KeyStoreInfo to copy from - */ - KeyStoreInfo & operator=(const KeyStoreInfo &from); + \param from the KeyStoreInfo to copy from + */ + KeyStoreInfo &operator=(const KeyStoreInfo &from); - /** - Test if this object is valid + /** + Test if this object is valid - \return true if the object is not valid - */ - bool isNull() const; + \return true if the object is not valid + */ + bool isNull() const; - /** - The Type of KeyStore that this KeyStoreInfo object - describes. - */ - KeyStore::Type type() const; + /** + The Type of KeyStore that this KeyStoreInfo object + describes. + */ + KeyStore::Type type() const; - /** - The unique identification of the KeyStore that - this KeyStoreInfo object describes. - */ - QString id() const; + /** + The unique identification of the KeyStore that + this KeyStoreInfo object describes. + */ + QString id() const; - /** - The descriptive name of the KeyStore that this - KeyStoreInfo object describes. - */ - QString name() const; + /** + The descriptive name of the KeyStore that this + KeyStoreInfo object describes. + */ + QString name() const; private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** @@ -708,89 +707,89 @@ */ class QCA_EXPORT KeyStoreManager : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Create a new KeyStoreManager - - \param parent the parent for this object - */ - KeyStoreManager(QObject *parent = 0); - ~KeyStoreManager(); - - /** - Initialize all key store providers - */ - static void start(); - - /** - Initialize a specific key store provider - - \param provider the name of the provider to start - */ - static void start(const QString &provider); - - /** - Indicates if the manager is busy looking for key stores - */ - bool isBusy() const; - - /** - Blocks until the manager is done looking for key stores - */ - void waitForBusyFinished(); - - /** - A list of all the key stores - */ - QStringList keyStores() const; - - /** - The diagnostic result of key store operations, such as - warnings and errors - */ - static QString diagnosticText(); - - /** - Clears the diagnostic result log - */ - static void clearDiagnosticText(); - - /** - If you are not using the eventloop, call this to update - the object state to the present - */ - void sync(); + /** + Create a new KeyStoreManager + + \param parent the parent for this object + */ + KeyStoreManager(QObject *parent = 0); + ~KeyStoreManager(); + + /** + Initialize all key store providers + */ + static void start(); + + /** + Initialize a specific key store provider + + \param provider the name of the provider to start + */ + static void start(const QString &provider); + + /** + Indicates if the manager is busy looking for key stores + */ + bool isBusy() const; + + /** + Blocks until the manager is done looking for key stores + */ + void waitForBusyFinished(); + + /** + A list of all the key stores + */ + QStringList keyStores() const; + + /** + The diagnostic result of key store operations, such as + warnings and errors + */ + static QString diagnosticText(); + + /** + Clears the diagnostic result log + */ + static void clearDiagnosticText(); + + /** + If you are not using the eventloop, call this to update + the object state to the present + */ + void sync(); Q_SIGNALS: - /** - emitted when the manager has started looking for key stores - */ - void busyStarted(); + /** + emitted when the manager has started looking for key stores + */ + void busyStarted(); - /** - emitted when the manager has finished looking for key stores - */ - void busyFinished(); + /** + emitted when the manager has finished looking for key stores + */ + void busyFinished(); - /** - emitted when a new key store becomes available + /** + emitted when a new key store becomes available - \param id the name of the key store that has become available - */ - void keyStoreAvailable(const QString &id); + \param id the name of the key store that has become available + */ + void keyStoreAvailable(const QString &id); private: - Q_DISABLE_COPY(KeyStoreManager) + Q_DISABLE_COPY(KeyStoreManager) - friend class KeyStoreManagerPrivate; - KeyStoreManagerPrivate *d; + friend class KeyStoreManagerPrivate; + KeyStoreManagerPrivate *d; - friend class Global; - friend class KeyStorePrivate; + friend class Global; + friend class KeyStorePrivate; - static void scan(); - static void shutdown(); + static void scan(); + static void shutdown(); }; } diff --git a/include/QtCrypto/qca_publickey.h b/include/QtCrypto/qca_publickey.h --- a/include/QtCrypto/qca_publickey.h +++ b/include/QtCrypto/qca_publickey.h @@ -36,7 +36,8 @@ #include #include "qca_core.h" -namespace QCA { +namespace QCA +{ class PublicKey; class PrivateKey; @@ -51,12 +52,11 @@ /** Encryption algorithms */ -enum EncryptionAlgorithm -{ - EME_PKCS1v15, ///< Block type 2 (PKCS#1, Version 1.5) - EME_PKCS1_OAEP, ///< Optimal asymmetric encryption padding (PKCS#1, Version 2.0) - EME_PKCS1v15_SSL, ///< PKCS#1, Version 1.5 with an SSL-specific modification - EME_NO_PADDING ///< Raw RSA encryption +enum EncryptionAlgorithm { + EME_PKCS1v15, ///< Block type 2 (PKCS#1, Version 1.5) + EME_PKCS1_OAEP, ///< Optimal asymmetric encryption padding (PKCS#1, Version 2.0) + EME_PKCS1v15_SSL, ///< PKCS#1, Version 1.5 with an SSL-specific modification + EME_NO_PADDING ///< Raw RSA encryption }; /** @@ -70,79 +70,74 @@ "openssl rsautl -verify" and comparing with sha1sum), because that would not take the EMSA3 payload format into consideration. */ -enum SignatureAlgorithm -{ - SignatureUnknown, ///< Unknown signing algorithm - EMSA1_SHA1, ///< SHA1, with EMSA1 (IEEE1363-2000) encoding (this is the usual DSA algorithm - FIPS186) - EMSA3_SHA1, ///< SHA1, with EMSA3 (ie PKCS#1 Version 1.5) encoding - EMSA3_MD5, ///< MD5, with EMSA3 (ie PKCS#1 Version 1.5) encoding (this is the usual RSA algorithm) - EMSA3_MD2, ///< MD2, with EMSA3 (ie PKCS#1 Version 1.5) encoding - EMSA3_RIPEMD160, ///< RIPEMD160, with EMSA3 (ie PKCS#1 Version 1.5) encoding - EMSA3_Raw, ///< EMSA3 without computing a message digest or a DigestInfo encoding (identical to PKCS#11's CKM_RSA_PKCS mechanism) - EMSA3_SHA224, ///< SHA224, with EMSA3 (ie PKCS#1 Version 1.5) encoding - EMSA3_SHA256, ///< SHA256, with EMSA3 (ie PKCS#1 Version 1.5) encoding - EMSA3_SHA384, ///< SHA384, with EMSA3 (ie PKCS#1 Version 1.5) encoding - EMSA3_SHA512 ///< SHA512, with EMSA3 (ie PKCS#1 Version 1.5) encoding +enum SignatureAlgorithm { + SignatureUnknown, ///< Unknown signing algorithm + EMSA1_SHA1, ///< SHA1, with EMSA1 (IEEE1363-2000) encoding (this is the usual DSA algorithm - FIPS186) + EMSA3_SHA1, ///< SHA1, with EMSA3 (ie PKCS#1 Version 1.5) encoding + EMSA3_MD5, ///< MD5, with EMSA3 (ie PKCS#1 Version 1.5) encoding (this is the usual RSA algorithm) + EMSA3_MD2, ///< MD2, with EMSA3 (ie PKCS#1 Version 1.5) encoding + EMSA3_RIPEMD160, ///< RIPEMD160, with EMSA3 (ie PKCS#1 Version 1.5) encoding + EMSA3_Raw, ///< EMSA3 without computing a message digest or a DigestInfo encoding (identical to PKCS#11's CKM_RSA_PKCS mechanism) + EMSA3_SHA224, ///< SHA224, with EMSA3 (ie PKCS#1 Version 1.5) encoding + EMSA3_SHA256, ///< SHA256, with EMSA3 (ie PKCS#1 Version 1.5) encoding + EMSA3_SHA384, ///< SHA384, with EMSA3 (ie PKCS#1 Version 1.5) encoding + EMSA3_SHA512 ///< SHA512, with EMSA3 (ie PKCS#1 Version 1.5) encoding }; /** Signature formats (DSA only) */ -enum SignatureFormat -{ - DefaultFormat, ///< For DSA, this is the same as IEEE_1363 - IEEE_1363, ///< 40-byte format from IEEE 1363 (Botan/.NET) - DERSequence ///< Signature wrapped in DER formatting (OpenSSL/Java) +enum SignatureFormat { + DefaultFormat, ///< For DSA, this is the same as IEEE_1363 + IEEE_1363, ///< 40-byte format from IEEE 1363 (Botan/.NET) + DERSequence ///< Signature wrapped in DER formatting (OpenSSL/Java) }; /** Password-based encryption */ -enum PBEAlgorithm -{ - PBEDefault, ///< Use modern default (same as PBES2_TripleDES_SHA1) - PBES2_DES_SHA1, ///< PKCS#5 v2.0 DES/CBC,SHA1 - PBES2_TripleDES_SHA1, ///< PKCS#5 v2.0 TripleDES/CBC,SHA1 - PBES2_AES128_SHA1, ///< PKCS#5 v2.0 AES-128/CBC,SHA1 - PBES2_AES192_SHA1, ///< PKCS#5 v2.0 AES-192/CBC,SHA1 - PBES2_AES256_SHA1 ///< PKCS#5 v2.0 AES-256/CBC,SHA1 +enum PBEAlgorithm { + PBEDefault, ///< Use modern default (same as PBES2_TripleDES_SHA1) + PBES2_DES_SHA1, ///< PKCS#5 v2.0 DES/CBC,SHA1 + PBES2_TripleDES_SHA1, ///< PKCS#5 v2.0 TripleDES/CBC,SHA1 + PBES2_AES128_SHA1, ///< PKCS#5 v2.0 AES-128/CBC,SHA1 + PBES2_AES192_SHA1, ///< PKCS#5 v2.0 AES-192/CBC,SHA1 + PBES2_AES256_SHA1 ///< PKCS#5 v2.0 AES-256/CBC,SHA1 }; /** Return value from a format conversion Note that if you are checking for any result other than ConvertGood, then you may be introducing a provider specific dependency. */ -enum ConvertResult -{ - ConvertGood, ///< Conversion succeeded, results should be valid - ErrorDecode, ///< General failure in the decode stage - ErrorPassphrase, ///< Failure because of incorrect passphrase - ErrorFile ///< Failure because of incorrect file +enum ConvertResult { + ConvertGood, ///< Conversion succeeded, results should be valid + ErrorDecode, ///< General failure in the decode stage + ErrorPassphrase, ///< Failure because of incorrect passphrase + ErrorFile ///< Failure because of incorrect file }; /** Well known discrete logarithm group sets These sets are derived from three main sources: - Java Cryptographic Extensions, + Java Cryptographic Extensions, RFC2412 and RFC3526. */ -enum DLGroupSet -{ - DSA_512, ///< 512 bit group, for compatibility with JCE - DSA_768, ///< 768 bit group, for compatibility with JCE - DSA_1024, ///< 1024 bit group, for compatibility with JCE - IETF_768, ///< Group 1 from RFC 2412, Section E.1 - IETF_1024, ///< Group 2 from RFC 2412, Section E.2 - IETF_1536, ///< 1536-bit MODP Group ("group 5") from RFC3526 Section 2. - IETF_2048, ///< 2048-bit MODP Group ("group 14") from RFC3526 Section 3. - IETF_3072, ///< 3072-bit MODP Group ("group 15") from RFC3526 Section 4. - IETF_4096, ///< 4096-bit MODP Group ("group 16") from RFC3526 Section 5. - IETF_6144, ///< 6144-bit MODP Group ("group 17") from RFC3526 Section 6. - IETF_8192 ///< 8192-bit MODP Group ("group 18") from RFC3526 Section 7. +enum DLGroupSet { + DSA_512, ///< 512 bit group, for compatibility with JCE + DSA_768, ///< 768 bit group, for compatibility with JCE + DSA_1024, ///< 1024 bit group, for compatibility with JCE + IETF_768, ///< Group 1 from RFC 2412, Section E.1 + IETF_1024, ///< Group 2 from RFC 2412, Section E.2 + IETF_1536, ///< 1536-bit MODP Group ("group 5") from RFC3526 Section 2. + IETF_2048, ///< 2048-bit MODP Group ("group 14") from RFC3526 Section 3. + IETF_3072, ///< 3072-bit MODP Group ("group 15") from RFC3526 Section 4. + IETF_4096, ///< 4096-bit MODP Group ("group 16") from RFC3526 Section 5. + IETF_6144, ///< 6144-bit MODP Group ("group 17") from RFC3526 Section 6. + IETF_8192 ///< 8192-bit MODP Group ("group 18") from RFC3526 Section 7. }; @@ -170,71 +165,71 @@ class QCA_EXPORT DLGroup { public: - DLGroup(); + DLGroup(); - /** - Construct a discrete logarithm group from raw parameters + /** + Construct a discrete logarithm group from raw parameters - \param p the P parameter - \param q the Q parameter - \param g the G parameter - */ - DLGroup(const BigInteger &p, const BigInteger &q, const BigInteger &g); + \param p the P parameter + \param q the Q parameter + \param g the G parameter + */ + DLGroup(const BigInteger &p, const BigInteger &q, const BigInteger &g); - /** - Construct a discrete logarithm group from raw parameters + /** + Construct a discrete logarithm group from raw parameters - \param p the P parameter - \param g the G parameter - */ - DLGroup(const BigInteger &p, const BigInteger &g); + \param p the P parameter + \param g the G parameter + */ + DLGroup(const BigInteger &p, const BigInteger &g); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the group to copy from - */ - DLGroup(const DLGroup &from); - ~DLGroup(); + \param from the group to copy from + */ + DLGroup(const DLGroup &from); + ~DLGroup(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the DLGroup to copy from - */ - DLGroup & operator=(const DLGroup &from); + \param from the DLGroup to copy from + */ + DLGroup &operator=(const DLGroup &from); - /** - Provide a list of the supported group sets + /** + Provide a list of the supported group sets - \param provider the provider to report which group sets are - available. If not specified, all providers will be checked - */ - static QList supportedGroupSets(const QString &provider = QString()); + \param provider the provider to report which group sets are + available. If not specified, all providers will be checked + */ + static QList supportedGroupSets(const QString &provider = QString()); - /** - Test if the group is empty - */ - bool isNull() const; + /** + Test if the group is empty + */ + bool isNull() const; - /** - Provide the p component of the group - */ - BigInteger p() const; + /** + Provide the p component of the group + */ + BigInteger p() const; - /** - Provide the q component of the group - */ - BigInteger q() const; + /** + Provide the q component of the group + */ + BigInteger q() const; - /** - Provide the g component of the group - */ - BigInteger g() const; + /** + Provide the g component of the group + */ + BigInteger g() const; private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -249,270 +244,270 @@ class QCA_EXPORT PKey : public Algorithm { public: - /** - Types of public key cryptography keys supported by QCA - */ - enum Type { - RSA, ///< RSA key - DSA, ///< DSA key - DH ///< Diffie Hellman key - }; - - /** - Standard constructor - */ - PKey(); - - /** - Standard copy constructor - - \param from the key to copy from - */ - PKey(const PKey &from); - - ~PKey(); - - /** - Standard assignment operator - - \param from the PKey to copy from - */ - PKey & operator=(const PKey &from); - - /** - Test what types of keys are supported. - - Normally you would just test if the capability is present, however - for PKey, you also need to test which types of keys are available. - So if you want to figure out if RSA keys are supported, you need to - do something like: - \code -if(!QCA::isSupported("pkey") || - !QCA::PKey::supportedTypes().contains(QCA::PKey::RSA)) -{ - // then there is no RSA key support -} -else -{ - // there is RSA key support -} - \endcode - - To make things a bit more complex, supportedTypes() only - checks for basic functionality. If you want to check that - you can do operations with PEM or DER (eg toPEM(), fromPEM(), and - the equivalent DER and PEMfile operations, plus anything else - that uses them, including the constructor form that takes a - fileName), then you need to check for supportedIOTypes() instead. - - \param provider the name of the provider to use, if a particular - provider is required. - - \sa supportedIOTypes() - */ - static QList supportedTypes(const QString &provider = QString()); - - /** - Test what types of keys are supported for IO operations - - If you are using PKey DER or PEM operations, then you need - to check for appropriate support using this method. For example, - if you want to check if you can export or import an RSA key, then - you need to do something like: - \code -if(!QCA::isSupported("pkey") || - !QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA)) -{ - // then there is no RSA key IO support -} -else -{ - // there is RSA key IO support -} - \endcode - - Note that if you only want to check for basic functionality - (ie not PEM or DER import/export), then you can use - supportedTypes(). There is no need to use both - if the key type - is supported for IO, then is also supported for basic operations. - - \param provider the name of the provider to use, if a particular - provider is required. - - \sa supportedTypes() - */ - static QList supportedIOTypes(const QString &provider = QString()); - - /** - Test if the key is null (empty) - - \return true if the key is null - */ - bool isNull() const; - - /** - Report the Type of key (eg RSA, DSA or Diffie Hellman) - - \sa isRSA, isDSA and isDH for boolean tests. - */ - Type type() const; - - /** - Report the number of bits in the key - */ - int bitSize() const; - - /** - Test if the key is an RSA key - */ - bool isRSA() const; - - /** - Test if the key is a DSA key - */ - bool isDSA() const; - - /** - Test if the key is a Diffie Hellman key - */ - bool isDH() const; - - /** - Test if the key is a public key - */ - bool isPublic() const; - - /** - Test if the key is a private key - */ - bool isPrivate() const; - - /** - Test if the key data can be exported. If the key resides on a - smart card or other such device, this will likely return false. - */ - bool canExport() const; - - /** - Test if the key can be used for key agreement - */ - bool canKeyAgree() const; - - /** - Interpret this key as a PublicKey - - \sa toRSAPublicKey(), toDSAPublicKey() and toDHPublicKey() - for protected forms of this call. - */ - PublicKey toPublicKey() const; - - /** - Interpret this key as a PrivateKey - */ - PrivateKey toPrivateKey() const; - - /** - test if two keys are equal - - \param a the key to compare with this key - */ - bool operator==(const PKey &a) const; - - /** - test if two keys are not equal - - \param a the key to compare with this key - */ - bool operator!=(const PKey &a) const; + /** + Types of public key cryptography keys supported by QCA + */ + enum Type { + RSA, ///< RSA key + DSA, ///< DSA key + DH ///< Diffie Hellman key + }; + + /** + Standard constructor + */ + PKey(); + + /** + Standard copy constructor + + \param from the key to copy from + */ + PKey(const PKey &from); + + ~PKey(); + + /** + Standard assignment operator + + \param from the PKey to copy from + */ + PKey &operator=(const PKey &from); + + /** + Test what types of keys are supported. + + Normally you would just test if the capability is present, however + for PKey, you also need to test which types of keys are available. + So if you want to figure out if RSA keys are supported, you need to + do something like: + \code + if(!QCA::isSupported("pkey") || + !QCA::PKey::supportedTypes().contains(QCA::PKey::RSA)) + { + // then there is no RSA key support + } + else + { + // there is RSA key support + } + \endcode + + To make things a bit more complex, supportedTypes() only + checks for basic functionality. If you want to check that + you can do operations with PEM or DER (eg toPEM(), fromPEM(), and + the equivalent DER and PEMfile operations, plus anything else + that uses them, including the constructor form that takes a + fileName), then you need to check for supportedIOTypes() instead. + + \param provider the name of the provider to use, if a particular + provider is required. + + \sa supportedIOTypes() + */ + static QList supportedTypes(const QString &provider = QString()); + + /** + Test what types of keys are supported for IO operations + + If you are using PKey DER or PEM operations, then you need + to check for appropriate support using this method. For example, + if you want to check if you can export or import an RSA key, then + you need to do something like: + \code + if(!QCA::isSupported("pkey") || + !QCA::PKey::supportedIOTypes().contains(QCA::PKey::RSA)) + { + // then there is no RSA key IO support + } + else + { + // there is RSA key IO support + } + \endcode + + Note that if you only want to check for basic functionality + (ie not PEM or DER import/export), then you can use + supportedTypes(). There is no need to use both - if the key type + is supported for IO, then is also supported for basic operations. + + \param provider the name of the provider to use, if a particular + provider is required. + + \sa supportedTypes() + */ + static QList supportedIOTypes(const QString &provider = QString()); + + /** + Test if the key is null (empty) + + \return true if the key is null + */ + bool isNull() const; + + /** + Report the Type of key (eg RSA, DSA or Diffie Hellman) + + \sa isRSA, isDSA and isDH for boolean tests. + */ + Type type() const; + + /** + Report the number of bits in the key + */ + int bitSize() const; + + /** + Test if the key is an RSA key + */ + bool isRSA() const; + + /** + Test if the key is a DSA key + */ + bool isDSA() const; + + /** + Test if the key is a Diffie Hellman key + */ + bool isDH() const; + + /** + Test if the key is a public key + */ + bool isPublic() const; + + /** + Test if the key is a private key + */ + bool isPrivate() const; + + /** + Test if the key data can be exported. If the key resides on a + smart card or other such device, this will likely return false. + */ + bool canExport() const; + + /** + Test if the key can be used for key agreement + */ + bool canKeyAgree() const; + + /** + Interpret this key as a PublicKey + + \sa toRSAPublicKey(), toDSAPublicKey() and toDHPublicKey() + for protected forms of this call. + */ + PublicKey toPublicKey() const; + + /** + Interpret this key as a PrivateKey + */ + PrivateKey toPrivateKey() const; + + /** + test if two keys are equal + + \param a the key to compare with this key + */ + bool operator==(const PKey &a) const; + + /** + test if two keys are not equal + + \param a the key to compare with this key + */ + bool operator!=(const PKey &a) const; protected: - /** - Create a key of the specified type + /** + Create a key of the specified type - \param type the name of the type of key to create - \param provider the name of the provider to create the key in - */ - PKey(const QString &type, const QString &provider); + \param type the name of the type of key to create + \param provider the name of the provider to create the key in + */ + PKey(const QString &type, const QString &provider); - /** - Set the key + /** + Set the key - \param k the key to assign from - */ - void set(const PKey &k); + \param k the key to assign from + */ + void set(const PKey &k); - /** - Interpret this key as an RSAPublicKey + /** + Interpret this key as an RSAPublicKey - \note This function is essentially a convenience cast - if the - key was created as a DSA key, this function cannot turn it into - an RSA key. + \note This function is essentially a convenience cast - if the + key was created as a DSA key, this function cannot turn it into + an RSA key. - \sa toPublicKey() for the public version of this method - */ - RSAPublicKey toRSAPublicKey() const; + \sa toPublicKey() for the public version of this method + */ + RSAPublicKey toRSAPublicKey() const; - /** - Interpret this key as an RSAPrivateKey + /** + Interpret this key as an RSAPrivateKey - \note This function is essentially a convenience cast - if the - key was created as a DSA key, this function cannot turn it into - a RSA key. + \note This function is essentially a convenience cast - if the + key was created as a DSA key, this function cannot turn it into + a RSA key. - \sa toPrivateKey() for the public version of this method - */ - RSAPrivateKey toRSAPrivateKey() const; + \sa toPrivateKey() for the public version of this method + */ + RSAPrivateKey toRSAPrivateKey() const; - /** - Interpret this key as an DSAPublicKey + /** + Interpret this key as an DSAPublicKey - \note This function is essentially a convenience cast - if the - key was created as an RSA key, this function cannot turn it into - a DSA key. + \note This function is essentially a convenience cast - if the + key was created as an RSA key, this function cannot turn it into + a DSA key. - \sa toPublicKey() for the public version of this method - */ - DSAPublicKey toDSAPublicKey() const; + \sa toPublicKey() for the public version of this method + */ + DSAPublicKey toDSAPublicKey() const; - /** - Interpret this key as a DSAPrivateKey + /** + Interpret this key as a DSAPrivateKey - \note This function is essentially a convenience cast - if the - key was created as an RSA key, this function cannot turn it into - a DSA key. + \note This function is essentially a convenience cast - if the + key was created as an RSA key, this function cannot turn it into + a DSA key. - \sa toPrivateKey() for the public version of this method - */ - DSAPrivateKey toDSAPrivateKey() const; + \sa toPrivateKey() for the public version of this method + */ + DSAPrivateKey toDSAPrivateKey() const; - /** - Interpret this key as an DHPublicKey + /** + Interpret this key as an DHPublicKey - \note This function is essentially a convenience cast - if the - key was created as a DSA key, this function cannot turn it into - a DH key. + \note This function is essentially a convenience cast - if the + key was created as a DSA key, this function cannot turn it into + a DH key. - \sa toPublicKey() for the public version of this method - */ - DHPublicKey toDHPublicKey() const; + \sa toPublicKey() for the public version of this method + */ + DHPublicKey toDHPublicKey() const; - /** - Interpret this key as a DHPrivateKey + /** + Interpret this key as a DHPrivateKey - \note This function is essentially a convenience cast - if the - key was created as a DSA key, this function cannot turn it into - a DH key. + \note This function is essentially a convenience cast - if the + key was created as a DSA key, this function cannot turn it into + a DH key. - \sa toPrivateKey() for the public version of this method - */ - DHPrivateKey toDHPrivateKey() const; + \sa toPrivateKey() for the public version of this method + */ + DHPrivateKey toDHPrivateKey() const; private: - void assignToPublic(PKey *dest) const; - void assignToPrivate(PKey *dest) const; + void assignToPublic(PKey *dest) const; + void assignToPrivate(PKey *dest) const; - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -526,293 +521,293 @@ class QCA_EXPORT PublicKey : public PKey { public: - /** - Create an empty (null) public key - */ - PublicKey(); - - /** - Create a public key based on a specified private key - - \param k the private key to extract the public key parts from - */ - PublicKey(const PrivateKey &k); - - /** - Import a public key from a PEM representation in a file - - \param fileName the name of the file containing the public key - - \sa fromPEMFile for an alternative method - */ - PublicKey(const QString &fileName); - - /** - Copy constructor - - \param from the PublicKey to copy from - */ - PublicKey(const PublicKey &from); - - ~PublicKey(); - - /** - Assignment operator - - \param from the PublicKey to copy from - */ - PublicKey & operator=(const PublicKey &from); + /** + Create an empty (null) public key + */ + PublicKey(); - /** - Convenience method to convert this key to an RSAPublicKey + /** + Create a public key based on a specified private key - Note that if the key is not an RSA key (eg it is DSA or DH), - then this will produce a null key. - */ - RSAPublicKey toRSA() const; + \param k the private key to extract the public key parts from + */ + PublicKey(const PrivateKey &k); - /** - Convenience method to convert this key to a DSAPublicKey + /** + Import a public key from a PEM representation in a file - Note that if the key is not an DSA key (eg it is RSA or DH), - then this will produce a null key. - */ - DSAPublicKey toDSA() const; + \param fileName the name of the file containing the public key - /** - Convenience method to convert this key to a DHPublicKey + \sa fromPEMFile for an alternative method + */ + PublicKey(const QString &fileName); - Note that if the key is not an DH key (eg it is DSA or RSA), - then this will produce a null key. - */ - DHPublicKey toDH() const; + /** + Copy constructor - /** - Test if this key can be used for encryption + \param from the PublicKey to copy from + */ + PublicKey(const PublicKey &from); - \return true if the key can be used for encryption - */ - bool canEncrypt() const; + ~PublicKey(); - /** - Test if this key can be used for decryption + /** + Assignment operator - \return true if the key can be used for decryption - */ - bool canDecrypt() const; + \param from the PublicKey to copy from + */ + PublicKey &operator=(const PublicKey &from); - /** - Test if the key can be used for verifying signatures + /** + Convenience method to convert this key to an RSAPublicKey - \return true of the key can be used for verification - */ - bool canVerify() const; + Note that if the key is not an RSA key (eg it is DSA or DH), + then this will produce a null key. + */ + RSAPublicKey toRSA() const; + + /** + Convenience method to convert this key to a DSAPublicKey - /** - The maximum message size that can be encrypted with a specified - algorithm + Note that if the key is not an DSA key (eg it is RSA or DH), + then this will produce a null key. + */ + DSAPublicKey toDSA() const; - \param alg the algorithm to check - */ - int maximumEncryptSize(EncryptionAlgorithm alg) const; + /** + Convenience method to convert this key to a DHPublicKey - /** - Encrypt a message using a specified algorithm + Note that if the key is not an DH key (eg it is DSA or RSA), + then this will produce a null key. + */ + DHPublicKey toDH() const; - \param a the message to encrypt - \param alg the algorithm to use - */ - SecureArray encrypt(const SecureArray &a, EncryptionAlgorithm alg); + /** + Test if this key can be used for encryption - /** - Decrypt the message + \return true if the key can be used for encryption + */ + bool canEncrypt() const; - \param in the cipher (encrypted) data - \param out the plain text data - \param alg the algorithm to use + /** + Test if this key can be used for decryption - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg); + \return true if the key can be used for decryption + */ + bool canDecrypt() const; - /** - Initialise the signature verification process + /** + Test if the key can be used for verifying signatures - \param alg the algorithm to use for signing - \param format the specific format to use, for DSA - */ - void startVerify(SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); + \return true of the key can be used for verification + */ + bool canVerify() const; - /** - Update the signature verification process with more data + /** + The maximum message size that can be encrypted with a specified + algorithm - \param a the array containing the data that should be added to the signature - */ - void update(const MemoryRegion &a); - - /** - Check the signature is valid for the message - - The process to check that a signature is correct is shown below: - \code -// note that pubkey is a PublicKey -if( pubkey.canVerify() ) -{ - pubkey.startVerify( QCA::EMSA3_MD5 ); - pubkey.update( theMessage ); // might be called multiple times - if ( pubkey.validSignature( theSignature ) ) - { - // then signature is valid - } - else - { - // then signature is invalid - } -} - \endcode - - \param sig the signature to check - - \return true if the signature is correct - */ - bool validSignature(const QByteArray &sig); - - /** - Single step message verification - - If you have the whole message to be verified, then this offers a - more convenient approach to verification. - - \param a the message to check the signature on - \param sig the signature to be checked - \param alg the algorithm to use - \param format the signature format to use, for DSA - - \return true if the signature is valid for the message - */ - bool verifyMessage(const MemoryRegion &a, const QByteArray &sig, SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); - - /** - Export the key in Distinguished Encoding Rules (DER) format - */ - QByteArray toDER() const; - - /** - Export the key in Privacy Enhanced Mail (PEM) format - - \sa toPEMFile provides a convenient way to save the PEM encoded key - to a file - \sa fromPEM provides an inverse of toPEM, converting the PEM - encoded key back to a PublicKey - */ - QString toPEM() const; - - /** - Export the key in Privacy Enhanced Mail (PEM) to a file - - \param fileName the name (and path, if necessary) of the file to - save the PEM encoded key to. - - \sa toPEM for a version that exports to a QString, which may be - useful if you need to do more sophisticated handling - \sa fromPEMFile provides an inverse of toPEMFile, reading a PEM - encoded key from a file - */ - bool toPEMFile(const QString &fileName) const; - - /** - Import a key in Distinguished Encoding Rules (DER) format - - This function takes a binary array, which is assumed to contain a - public key in DER encoding, and returns the key. Unless you don't - care whether the import succeeded, you should test the result, as - shown below. - - \code -QCA::ConvertResult conversionResult; -QCA::PublicKey publicKey = QCA::PublicKey::fromDER(keyArray, &conversionResult); -if (! QCA::ConvertGood == conversionResult) -{ - std::cout << "Public key read failed" << std::endl; -} - \endcode - - \param a the array containing a DER encoded key - \param result pointer to a variable, which returns whether the - conversion succeeded (ConvertGood) or not - \param provider the name of the provider to use for the import. - */ - static PublicKey fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); - - /** - Import a key in Privacy Enhanced Mail (PEM) format - - This function takes a string, which is assumed to contain a public - key in PEM encoding, and returns that key. Unless you don't care - whether the import succeeded, you should test the result, as shown - below. - - \code -QCA::ConvertResult conversionResult; -QCA::PublicKey publicKey = QCA::PublicKey::fromPEM(keyAsString, &conversionResult); -if (! QCA::ConvertGood == conversionResult) -{ - std::cout << "Public key read failed" << std::endl; -} - \endcode - - \param s the string containing a PEM encoded key - \param result pointer to a variable, which returns whether the - conversion succeeded (ConvertGood) or not - \param provider the name of the provider to use for the import. - - \sa toPEM, which provides an inverse of fromPEM() - \sa fromPEMFile, which provides an import direct from a file. - */ - static PublicKey fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); - - /** - Import a key in Privacy Enhanced Mail (PEM) format from a file - - This function takes the name of a file, which is assumed to contain - a public key in PEM encoding, and returns that key. Unless you - don't care whether the import succeeded, you should test the - result, as shown below. - - \code -QCA::ConvertResult conversionResult; -QCA::PublicKey publicKey = QCA::PublicKey::fromPEMFile(fileName, &conversionResult); -if (! QCA::ConvertGood == conversionResult) -{ - std::cout << "Public key read failed" << std::endl; -} - \endcode + \param alg the algorithm to check + */ + int maximumEncryptSize(EncryptionAlgorithm alg) const; - \param fileName a string containing the name of the file - \param result pointer to a variable, which returns whether the - conversion succeeded (ConvertGood) or not - \param provider the name of the provider to use for the import. + /** + Encrypt a message using a specified algorithm + + \param a the message to encrypt + \param alg the algorithm to use + */ + SecureArray encrypt(const SecureArray &a, EncryptionAlgorithm alg); - \sa toPEMFile, which provides an inverse of fromPEMFile() - \sa fromPEM, which provides an import from a string + /** + Decrypt the message + + \param in the cipher (encrypted) data + \param out the plain text data + \param alg the algorithm to use - \note there is also a constructor form that can import from a file - */ - static PublicKey fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg); + + /** + Initialise the signature verification process + + \param alg the algorithm to use for signing + \param format the specific format to use, for DSA + */ + void startVerify(SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); + + /** + Update the signature verification process with more data + + \param a the array containing the data that should be added to the signature + */ + void update(const MemoryRegion &a); + + /** + Check the signature is valid for the message + + The process to check that a signature is correct is shown below: + \code + // note that pubkey is a PublicKey + if( pubkey.canVerify() ) + { + pubkey.startVerify( QCA::EMSA3_MD5 ); + pubkey.update( theMessage ); // might be called multiple times + if ( pubkey.validSignature( theSignature ) ) + { + // then signature is valid + } + else + { + // then signature is invalid + } + } + \endcode + + \param sig the signature to check + + \return true if the signature is correct + */ + bool validSignature(const QByteArray &sig); + + /** + Single step message verification + + If you have the whole message to be verified, then this offers a + more convenient approach to verification. + + \param a the message to check the signature on + \param sig the signature to be checked + \param alg the algorithm to use + \param format the signature format to use, for DSA + + \return true if the signature is valid for the message + */ + bool verifyMessage(const MemoryRegion &a, const QByteArray &sig, SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); + + /** + Export the key in Distinguished Encoding Rules (DER) format + */ + QByteArray toDER() const; + + /** + Export the key in Privacy Enhanced Mail (PEM) format + + \sa toPEMFile provides a convenient way to save the PEM encoded key + to a file + \sa fromPEM provides an inverse of toPEM, converting the PEM + encoded key back to a PublicKey + */ + QString toPEM() const; + + /** + Export the key in Privacy Enhanced Mail (PEM) to a file + + \param fileName the name (and path, if necessary) of the file to + save the PEM encoded key to. + + \sa toPEM for a version that exports to a QString, which may be + useful if you need to do more sophisticated handling + \sa fromPEMFile provides an inverse of toPEMFile, reading a PEM + encoded key from a file + */ + bool toPEMFile(const QString &fileName) const; + + /** + Import a key in Distinguished Encoding Rules (DER) format + + This function takes a binary array, which is assumed to contain a + public key in DER encoding, and returns the key. Unless you don't + care whether the import succeeded, you should test the result, as + shown below. + + \code + QCA::ConvertResult conversionResult; + QCA::PublicKey publicKey = QCA::PublicKey::fromDER(keyArray, &conversionResult); + if (! QCA::ConvertGood == conversionResult) + { + std::cout << "Public key read failed" << std::endl; + } + \endcode + + \param a the array containing a DER encoded key + \param result pointer to a variable, which returns whether the + conversion succeeded (ConvertGood) or not + \param provider the name of the provider to use for the import. + */ + static PublicKey fromDER(const QByteArray &a, ConvertResult *result = 0, const QString &provider = QString()); + + /** + Import a key in Privacy Enhanced Mail (PEM) format + + This function takes a string, which is assumed to contain a public + key in PEM encoding, and returns that key. Unless you don't care + whether the import succeeded, you should test the result, as shown + below. + + \code + QCA::ConvertResult conversionResult; + QCA::PublicKey publicKey = QCA::PublicKey::fromPEM(keyAsString, &conversionResult); + if (! QCA::ConvertGood == conversionResult) + { + std::cout << "Public key read failed" << std::endl; + } + \endcode + + \param s the string containing a PEM encoded key + \param result pointer to a variable, which returns whether the + conversion succeeded (ConvertGood) or not + \param provider the name of the provider to use for the import. + + \sa toPEM, which provides an inverse of fromPEM() + \sa fromPEMFile, which provides an import direct from a file. + */ + static PublicKey fromPEM(const QString &s, ConvertResult *result = 0, const QString &provider = QString()); + + /** + Import a key in Privacy Enhanced Mail (PEM) format from a file + + This function takes the name of a file, which is assumed to contain + a public key in PEM encoding, and returns that key. Unless you + don't care whether the import succeeded, you should test the + result, as shown below. + + \code + QCA::ConvertResult conversionResult; + QCA::PublicKey publicKey = QCA::PublicKey::fromPEMFile(fileName, &conversionResult); + if (! QCA::ConvertGood == conversionResult) + { + std::cout << "Public key read failed" << std::endl; + } + \endcode + + \param fileName a string containing the name of the file + \param result pointer to a variable, which returns whether the + conversion succeeded (ConvertGood) or not + \param provider the name of the provider to use for the import. + + \sa toPEMFile, which provides an inverse of fromPEMFile() + \sa fromPEM, which provides an import from a string + + \note there is also a constructor form that can import from a file + */ + static PublicKey fromPEMFile(const QString &fileName, ConvertResult *result = 0, const QString &provider = QString()); protected: - /** - Create a new key of a specified type + /** + Create a new key of a specified type - \param type the type of key to create - \param provider the provider to use, if required - */ - PublicKey(const QString &type, const QString &provider); + \param type the type of key to create + \param provider the provider to use, if required + */ + PublicKey(const QString &type, const QString &provider); private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -826,284 +821,284 @@ class QCA_EXPORT PrivateKey : public PKey { public: - /** - Create an empty private key - */ - PrivateKey(); + /** + Create an empty private key + */ + PrivateKey(); - /** - Import a private key from a PEM representation in a file + /** + Import a private key from a PEM representation in a file - \param fileName the name of the file containing the private key - \param passphrase the pass phrase for the private key + \param fileName the name of the file containing the private key + \param passphrase the pass phrase for the private key - \sa fromPEMFile for an alternative method + \sa fromPEMFile for an alternative method - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - explicit PrivateKey(const QString &fileName, const SecureArray &passphrase = SecureArray()); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + explicit PrivateKey(const QString &fileName, const SecureArray &passphrase = SecureArray()); - /** - Copy constructor + /** + Copy constructor - \param from the PrivateKey to copy from - */ - PrivateKey(const PrivateKey &from); + \param from the PrivateKey to copy from + */ + PrivateKey(const PrivateKey &from); - ~PrivateKey(); + ~PrivateKey(); - /** - Assignment operator + /** + Assignment operator - \param from the PrivateKey to copy from - */ - PrivateKey & operator=(const PrivateKey &from); + \param from the PrivateKey to copy from + */ + PrivateKey &operator=(const PrivateKey &from); - /** - Interpret / convert the key to an RSA key - */ - RSAPrivateKey toRSA() const; + /** + Interpret / convert the key to an RSA key + */ + RSAPrivateKey toRSA() const; - /** - Interpret / convert the key to a DSA key - */ - DSAPrivateKey toDSA() const; + /** + Interpret / convert the key to a DSA key + */ + DSAPrivateKey toDSA() const; - /** - Interpret / convert the key to a Diffie-Hellman key - */ - DHPrivateKey toDH() const; + /** + Interpret / convert the key to a Diffie-Hellman key + */ + DHPrivateKey toDH() const; - /** - Test if this key can be used for decryption + /** + Test if this key can be used for decryption - \return true if the key can be used for decryption - */ - bool canDecrypt() const; + \return true if the key can be used for decryption + */ + bool canDecrypt() const; - /** - Test if this key can be used for encryption + /** + Test if this key can be used for encryption - \return true if the key can be used for encryption - */ - bool canEncrypt() const; + \return true if the key can be used for encryption + */ + bool canEncrypt() const; - /** - Test if this key can be used for signing + /** + Test if this key can be used for signing - \return true if the key can be used to make a signature - */ - bool canSign() const; + \return true if the key can be used to make a signature + */ + bool canSign() const; - /** - The maximum message size that can be encrypted with a specified - algorithm + /** + The maximum message size that can be encrypted with a specified + algorithm - \param alg the algorithm to check - */ - int maximumEncryptSize(EncryptionAlgorithm alg) const; + \param alg the algorithm to check + */ + int maximumEncryptSize(EncryptionAlgorithm alg) const; - /** - Decrypt the message + /** + Decrypt the message - \param in the cipher (encrypted) data - \param out the plain text data - \param alg the algorithm to use + \param in the cipher (encrypted) data + \param out the plain text data + \param alg the algorithm to use - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg); - /** - Encrypt a message using a specified algorithm + /** + Encrypt a message using a specified algorithm - \param a the message to encrypt - \param alg the algorithm to use - */ - SecureArray encrypt(const SecureArray &a, EncryptionAlgorithm alg); + \param a the message to encrypt + \param alg the algorithm to use + */ + SecureArray encrypt(const SecureArray &a, EncryptionAlgorithm alg); - /** - Initialise the message signature process + /** + Initialise the message signature process - \param alg the algorithm to use for the message signature process - \param format the signature format to use, for DSA + \param alg the algorithm to use for the message signature process + \param format the signature format to use, for DSA - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - void startSign(SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + void startSign(SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); - /** - Update the signature process + /** + Update the signature process - \param a the message to use to update the signature + \param a the message to use to update the signature - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - void update(const MemoryRegion &a); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + void update(const MemoryRegion &a); - /** - The resulting signature + /** + The resulting signature - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - QByteArray signature(); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + QByteArray signature(); - /** - One step signature process + /** + One step signature process - \param a the message to sign - \param alg the algorithm to use for the signature - \param format the signature format to use, for DSA + \param a the message to sign + \param alg the algorithm to use for the signature + \param format the signature format to use, for DSA - \return the signature + \return the signature - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - QByteArray signMessage(const MemoryRegion &a, SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + QByteArray signMessage(const MemoryRegion &a, SignatureAlgorithm alg, SignatureFormat format = DefaultFormat); - /** - Derive a shared secret key from a public key + /** + Derive a shared secret key from a public key - \param theirs the public key to derive from - */ - SymmetricKey deriveKey(const PublicKey &theirs); + \param theirs the public key to derive from + */ + SymmetricKey deriveKey(const PublicKey &theirs); - /** - List the supported Password Based Encryption Algorithms that can be - used to protect the key. + /** + List the supported Password Based Encryption Algorithms that can be + used to protect the key. - \param provider the provider to use, if a particular provider is - required - */ - static QList supportedPBEAlgorithms(const QString &provider = QString()); + \param provider the provider to use, if a particular provider is + required + */ + static QList supportedPBEAlgorithms(const QString &provider = QString()); - /** - Export the key in Distinguished Encoding Rules (DER) format + /** + Export the key in Distinguished Encoding Rules (DER) format - \param passphrase the pass phrase to use to protect the key - \param pbe the symmetric encryption algorithm to use to protect the - key + \param passphrase the pass phrase to use to protect the key + \param pbe the symmetric encryption algorithm to use to protect the + key - \sa fromDER provides an inverse of toDER, converting the DER - encoded key back to a PrivateKey - */ - SecureArray toDER(const SecureArray &passphrase = SecureArray(), PBEAlgorithm pbe = PBEDefault) const; + \sa fromDER provides an inverse of toDER, converting the DER + encoded key back to a PrivateKey + */ + SecureArray toDER(const SecureArray &passphrase = SecureArray(), PBEAlgorithm pbe = PBEDefault) const; - /** - Export the key in Privacy Enhanced Mail (PEM) format + /** + Export the key in Privacy Enhanced Mail (PEM) format - \param passphrase the pass phrase to use to protect the key - \param pbe the symmetric encryption algorithm to use to protect the - key + \param passphrase the pass phrase to use to protect the key + \param pbe the symmetric encryption algorithm to use to protect the + key - \sa toPEMFile provides a convenient way to save the PEM encoded key - to a file - \sa fromPEM provides an inverse of toPEM, converting the PEM - encoded key back to a PrivateKey - */ - QString toPEM(const SecureArray &passphrase = SecureArray(), PBEAlgorithm pbe = PBEDefault) const; + \sa toPEMFile provides a convenient way to save the PEM encoded key + to a file + \sa fromPEM provides an inverse of toPEM, converting the PEM + encoded key back to a PrivateKey + */ + QString toPEM(const SecureArray &passphrase = SecureArray(), PBEAlgorithm pbe = PBEDefault) const; - /** - Export the key in Privacy Enhanced Mail (PEM) format to a file + /** + Export the key in Privacy Enhanced Mail (PEM) format to a file - \param fileName the name (and path, if required) that the key - should be exported to. - \param passphrase the pass phrase to use to protect the key - \param pbe the symmetric encryption algorithm to use to protect the - key + \param fileName the name (and path, if required) that the key + should be exported to. + \param passphrase the pass phrase to use to protect the key + \param pbe the symmetric encryption algorithm to use to protect the + key - \return true if the export succeeds + \return true if the export succeeds - \sa toPEM provides a convenient way to save the PEM encoded key to - a file - \sa fromPEM provides an inverse of toPEM, converting the PEM - encoded key back to a PrivateKey - */ - bool toPEMFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), PBEAlgorithm pbe = PBEDefault) const; + \sa toPEM provides a convenient way to save the PEM encoded key to + a file + \sa fromPEM provides an inverse of toPEM, converting the PEM + encoded key back to a PrivateKey + */ + bool toPEMFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), PBEAlgorithm pbe = PBEDefault) const; - /** - Import the key from Distinguished Encoding Rules (DER) format + /** + Import the key from Distinguished Encoding Rules (DER) format - \param a the array containing the DER representation of the key - \param passphrase the pass phrase that is used to protect the key - \param result a pointer to a ConvertResult, that if specified, will - be set to reflect the result of the import - \param provider the provider to use, if a particular provider is - required + \param a the array containing the DER representation of the key + \param passphrase the pass phrase that is used to protect the key + \param result a pointer to a ConvertResult, that if specified, will + be set to reflect the result of the import + \param provider the provider to use, if a particular provider is + required - \sa toDER provides an inverse of fromDER, exporting the key to an - array + \sa toDER provides an inverse of fromDER, exporting the key to an + array - \sa QCA::KeyLoader for an asynchronous loader approach. + \sa QCA::KeyLoader for an asynchronous loader approach. - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - static PrivateKey fromDER(const SecureArray &a, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + static PrivateKey fromDER(const SecureArray &a, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); - /** - Import the key from Privacy Enhanced Mail (PEM) format + /** + Import the key from Privacy Enhanced Mail (PEM) format - \param s the string containing the PEM representation of the key - \param passphrase the pass phrase that is used to protect the key - \param result a pointer to a ConvertResult, that if specified, will - be set to reflect the result of the import - \param provider the provider to use, if a particular provider is - required + \param s the string containing the PEM representation of the key + \param passphrase the pass phrase that is used to protect the key + \param result a pointer to a ConvertResult, that if specified, will + be set to reflect the result of the import + \param provider the provider to use, if a particular provider is + required - \sa toPEM provides an inverse of fromPEM, exporting the key to a - string in PEM encoding. + \sa toPEM provides an inverse of fromPEM, exporting the key to a + string in PEM encoding. - \sa QCA::KeyLoader for an asynchronous loader approach. + \sa QCA::KeyLoader for an asynchronous loader approach. - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - static PrivateKey fromPEM(const QString &s, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + static PrivateKey fromPEM(const QString &s, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); - /** - Import the key in Privacy Enhanced Mail (PEM) format from a file + /** + Import the key in Privacy Enhanced Mail (PEM) format from a file - \param fileName the name (and path, if required) of the file - containing the PEM representation of the key - \param passphrase the pass phrase that is used to protect the key - \param result a pointer to a ConvertResult, that if specified, will - be set to reflect the result of the import - \param provider the provider to use, if a particular provider is - required + \param fileName the name (and path, if required) of the file + containing the PEM representation of the key + \param passphrase the pass phrase that is used to protect the key + \param result a pointer to a ConvertResult, that if specified, will + be set to reflect the result of the import + \param provider the provider to use, if a particular provider is + required - \sa toPEMFile provides an inverse of fromPEMFile - \sa fromPEM which allows import from a string + \sa toPEMFile provides an inverse of fromPEMFile + \sa fromPEM which allows import from a string - \sa QCA::KeyLoader for an asynchronous loader approach. + \sa QCA::KeyLoader for an asynchronous loader approach. - \note there is also a constructor form, that allows you to create - the key directly + \note there is also a constructor form, that allows you to create + the key directly - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - static PrivateKey fromPEMFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + static PrivateKey fromPEMFile(const QString &fileName, const SecureArray &passphrase = SecureArray(), ConvertResult *result = 0, const QString &provider = QString()); protected: - /** - Create a new private key + /** + Create a new private key - \param type the type of key to create - \param provider the provider to use, if a specific provider is - required. - */ - PrivateKey(const QString &type, const QString &provider); + \param type the type of key to create + \param provider the provider to use, if a specific provider is + required. + */ + PrivateKey(const QString &type, const QString &provider); private: - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -1119,132 +1114,132 @@ */ class QCA_EXPORT KeyGenerator : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Create a new key generator + /** + Create a new key generator - \param parent the parent object, if applicable - */ - KeyGenerator(QObject *parent = 0); + \param parent the parent object, if applicable + */ + KeyGenerator(QObject *parent = 0); - ~KeyGenerator(); - - /** - Test whether the key generator is set to operate in blocking mode, - or not + ~KeyGenerator(); + + /** + Test whether the key generator is set to operate in blocking mode, + or not - \return true if the key generator is in blocking mode + \return true if the key generator is in blocking mode - \sa setBlockingEnabled - */ - bool blockingEnabled() const; + \sa setBlockingEnabled + */ + bool blockingEnabled() const; - /** - Set whether the key generator is in blocking mode, nor not + /** + Set whether the key generator is in blocking mode, nor not - \param b if true, the key generator will be set to operate in - blocking mode, otherwise it will operate in non-blocking mode + \param b if true, the key generator will be set to operate in + blocking mode, otherwise it will operate in non-blocking mode - \sa blockingEnabled() - */ - void setBlockingEnabled(bool b); + \sa blockingEnabled() + */ + void setBlockingEnabled(bool b); - /** - Test if the key generator is currently busy, or not + /** + Test if the key generator is currently busy, or not - \return true if the key generator is busy generating a key already - */ - bool isBusy() const; + \return true if the key generator is busy generating a key already + */ + bool isBusy() const; - /** - Generate an RSA key of the specified length + /** + Generate an RSA key of the specified length - This method creates both the public key and corresponding private - key. You almost certainly want to extract the public key part out - - see PKey::toPublicKey for an easy way. + This method creates both the public key and corresponding private + key. You almost certainly want to extract the public key part out - + see PKey::toPublicKey for an easy way. - Key length is a tricky judgment - using less than 2048 is probably - being too liberal for long term use. Don't use less than 1024 - without serious analysis. + Key length is a tricky judgment - using less than 2048 is probably + being too liberal for long term use. Don't use less than 1024 + without serious analysis. - \param bits the length of key that is required - \param exp the exponent - typically 3, 17 or 65537 - \param provider the name of the provider to use, if a particular - provider is required - */ - PrivateKey createRSA(int bits, int exp = 65537, const QString &provider = QString()); + \param bits the length of key that is required + \param exp the exponent - typically 3, 17 or 65537 + \param provider the name of the provider to use, if a particular + provider is required + */ + PrivateKey createRSA(int bits, int exp = 65537, const QString &provider = QString()); - /** - Generate a DSA key + /** + Generate a DSA key - This method creates both the public key and corresponding private - key. You almost certainly want to extract the public key part out - - see PKey::toPublicKey for an easy way. + This method creates both the public key and corresponding private + key. You almost certainly want to extract the public key part out - + see PKey::toPublicKey for an easy way. - \param domain the discrete logarithm group that this key should be - generated from - \param provider the name of the provider to use, if a particular - provider is required + \param domain the discrete logarithm group that this key should be + generated from + \param provider the name of the provider to use, if a particular + provider is required - \note Not every DLGroup makes sense for DSA. You should use one of - DSA_512, DSA_768 and DSA_1024. - */ - PrivateKey createDSA(const DLGroup &domain, const QString &provider = QString()); + \note Not every DLGroup makes sense for DSA. You should use one of + DSA_512, DSA_768 and DSA_1024. + */ + PrivateKey createDSA(const DLGroup &domain, const QString &provider = QString()); - /** - Generate a Diffie-Hellman key + /** + Generate a Diffie-Hellman key - This method creates both the public key and corresponding private - key. You almost certainly want to extract the public key part out - - see PKey::toPublicKey for an easy way. + This method creates both the public key and corresponding private + key. You almost certainly want to extract the public key part out - + see PKey::toPublicKey for an easy way. - \param domain the discrete logarithm group that this key should be - generated from - \param provider the name of the provider to use, if a particular - provider is required - \note For compatibility, you should use one of the IETF_ groupsets - as the domain argument. - */ - PrivateKey createDH(const DLGroup &domain, const QString &provider = QString()); + \param domain the discrete logarithm group that this key should be + generated from + \param provider the name of the provider to use, if a particular + provider is required + \note For compatibility, you should use one of the IETF_ groupsets + as the domain argument. + */ + PrivateKey createDH(const DLGroup &domain, const QString &provider = QString()); - /** - Return the last generated key + /** + Return the last generated key - This is really only useful when you are working with non-blocking - key generation - */ - PrivateKey key() const; + This is really only useful when you are working with non-blocking + key generation + */ + PrivateKey key() const; - /** - Create a new discrete logarithm group + /** + Create a new discrete logarithm group - \param set the set of discrete logarithm parameters to generate - from - \param provider the name of the provider to use, if a particular - provider is required. - */ - DLGroup createDLGroup(QCA::DLGroupSet set, const QString &provider = QString()); + \param set the set of discrete logarithm parameters to generate + from + \param provider the name of the provider to use, if a particular + provider is required. + */ + DLGroup createDLGroup(QCA::DLGroupSet set, const QString &provider = QString()); - /** - The current discrete logarithm group - */ - DLGroup dlGroup() const; + /** + The current discrete logarithm group + */ + DLGroup dlGroup() const; Q_SIGNALS: - /** - Emitted when the key generation is complete. + /** + Emitted when the key generation is complete. - This is only used in non-blocking mode - */ - void finished(); + This is only used in non-blocking mode + */ + void finished(); private: - Q_DISABLE_COPY(KeyGenerator) + Q_DISABLE_COPY(KeyGenerator) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -1258,44 +1253,44 @@ class QCA_EXPORT RSAPublicKey : public PublicKey { public: - /** - Generate an empty RSA public key - */ - RSAPublicKey(); - - /** - Generate an RSA public key from specified parameters - - \param n the public key value - \param e the public key exponent - \param provider the provider to use, if a particular provider is - required - */ - RSAPublicKey(const BigInteger &n, const BigInteger &e, const QString &provider = QString()); - - /** - Extract the public key components from an RSA private key - - \param k the private key to use as the basis for the public key - */ - RSAPublicKey(const RSAPrivateKey &k); - - /** - The public key value - - This value is the actual public key value (the product of p and q, - the random prime numbers used to generate the RSA key), also known - as the public modulus. - */ - BigInteger n() const; - - /** - The public key exponent - - This value is the exponent chosen in the original key generator - step - */ - BigInteger e() const; + /** + Generate an empty RSA public key + */ + RSAPublicKey(); + + /** + Generate an RSA public key from specified parameters + + \param n the public key value + \param e the public key exponent + \param provider the provider to use, if a particular provider is + required + */ + RSAPublicKey(const BigInteger &n, const BigInteger &e, const QString &provider = QString()); + + /** + Extract the public key components from an RSA private key + + \param k the private key to use as the basis for the public key + */ + RSAPublicKey(const RSAPrivateKey &k); + + /** + The public key value + + This value is the actual public key value (the product of p and q, + the random prime numbers used to generate the RSA key), also known + as the public modulus. + */ + BigInteger n() const; + + /** + The public key exponent + + This value is the exponent chosen in the original key generator + step + */ + BigInteger e() const; }; /** @@ -1309,56 +1304,56 @@ class QCA_EXPORT RSAPrivateKey : public PrivateKey { public: - /** - Generate an empty RSA private key - */ - RSAPrivateKey(); - - /** - Generate an RSA private key from specified parameters - - \param n the public key value - \param e the public key exponent - \param p one of the two chosen primes - \param q the other of the two chosen primes - \param d inverse of the exponent, modulo (p-1)(q-1) - \param provider the provider to use, if a particular provider is - required - */ - RSAPrivateKey(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d, const QString &provider = QString()); - - /** - The public key value - - This value is the actual public key value (the product of p and q, - the random prime numbers used to generate the RSA key), also known - as the public modulus. - */ - BigInteger n() const; - - /** - The public key exponent - - This value is the exponent chosen in the original key generator - step - */ - BigInteger e() const; - - /** - One of the two random primes used to generate the private key - */ - BigInteger p() const; - - /** - The second of the two random primes used to generate the private - key - */ - BigInteger q() const; - - /** - The inverse of the exponent, module (p-1)(q-1) - */ - BigInteger d() const; + /** + Generate an empty RSA private key + */ + RSAPrivateKey(); + + /** + Generate an RSA private key from specified parameters + + \param n the public key value + \param e the public key exponent + \param p one of the two chosen primes + \param q the other of the two chosen primes + \param d inverse of the exponent, modulo (p-1)(q-1) + \param provider the provider to use, if a particular provider is + required + */ + RSAPrivateKey(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d, const QString &provider = QString()); + + /** + The public key value + + This value is the actual public key value (the product of p and q, + the random prime numbers used to generate the RSA key), also known + as the public modulus. + */ + BigInteger n() const; + + /** + The public key exponent + + This value is the exponent chosen in the original key generator + step + */ + BigInteger e() const; + + /** + One of the two random primes used to generate the private key + */ + BigInteger p() const; + + /** + The second of the two random primes used to generate the private + key + */ + BigInteger q() const; + + /** + The inverse of the exponent, module (p-1)(q-1) + */ + BigInteger d() const; }; /** @@ -1372,37 +1367,37 @@ class QCA_EXPORT DSAPublicKey : public PublicKey { public: - /** - Create an empty DSA public key - */ - DSAPublicKey(); - - /** - Create a DSA public key - - \param domain the discrete logarithm group to use - \param y the public random value - \param provider the provider to use, if a specific provider is - required - */ - DSAPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider = QString()); - - /** - Create a DSA public key from a specified private key - - \param k the DSA private key to use as the source - */ - DSAPublicKey(const DSAPrivateKey &k); - - /** - The discrete logarithm group that is being used - */ - DLGroup domain() const; - - /** - The public random value associated with this key - */ - BigInteger y() const; + /** + Create an empty DSA public key + */ + DSAPublicKey(); + + /** + Create a DSA public key + + \param domain the discrete logarithm group to use + \param y the public random value + \param provider the provider to use, if a specific provider is + required + */ + DSAPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider = QString()); + + /** + Create a DSA public key from a specified private key + + \param k the DSA private key to use as the source + */ + DSAPublicKey(const DSAPrivateKey &k); + + /** + The discrete logarithm group that is being used + */ + DLGroup domain() const; + + /** + The public random value associated with this key + */ + BigInteger y() const; }; /** @@ -1416,36 +1411,36 @@ class QCA_EXPORT DSAPrivateKey : public PrivateKey { public: - /** - Create an empty DSA private key - */ - DSAPrivateKey(); - - /** - Create a DSA public key - - \param domain the discrete logarithm group to use - \param y the public random value - \param x the private random value - \param provider the provider to use, if a specific provider is - required - */ - DSAPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider = QString()); - - /** - The discrete logarithm group that is being used - */ - DLGroup domain() const; - - /** - the public random value - */ - BigInteger y() const; - - /** - the private random value - */ - BigInteger x() const; + /** + Create an empty DSA private key + */ + DSAPrivateKey(); + + /** + Create a DSA public key + + \param domain the discrete logarithm group to use + \param y the public random value + \param x the private random value + \param provider the provider to use, if a specific provider is + required + */ + DSAPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider = QString()); + + /** + The discrete logarithm group that is being used + */ + DLGroup domain() const; + + /** + the public random value + */ + BigInteger y() const; + + /** + the private random value + */ + BigInteger x() const; }; /** @@ -1459,37 +1454,37 @@ class QCA_EXPORT DHPublicKey : public PublicKey { public: - /** - Create an empty Diffie-Hellman public key - */ - DHPublicKey(); - - /** - Create a Diffie-Hellman public key - - \param domain the discrete logarithm group to use - \param y the public random value - \param provider the provider to use, if a specific provider is - required - */ - DHPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider = QString()); - - /** - Create a Diffie-Hellman public key from a specified private key - - \param k the Diffie-Hellman private key to use as the source - */ - DHPublicKey(const DHPrivateKey &k); - - /** - The discrete logarithm group that is being used - */ - DLGroup domain() const; - - /** - The public random value associated with this key - */ - BigInteger y() const; + /** + Create an empty Diffie-Hellman public key + */ + DHPublicKey(); + + /** + Create a Diffie-Hellman public key + + \param domain the discrete logarithm group to use + \param y the public random value + \param provider the provider to use, if a specific provider is + required + */ + DHPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider = QString()); + + /** + Create a Diffie-Hellman public key from a specified private key + + \param k the Diffie-Hellman private key to use as the source + */ + DHPublicKey(const DHPrivateKey &k); + + /** + The discrete logarithm group that is being used + */ + DLGroup domain() const; + + /** + The public random value associated with this key + */ + BigInteger y() const; }; /** @@ -1503,36 +1498,36 @@ class QCA_EXPORT DHPrivateKey : public PrivateKey { public: - /** - Create an empty Diffie-Hellman private key - */ - DHPrivateKey(); - - /** - Create a Diffie-Hellman private key - - \param domain the discrete logarithm group to use - \param y the public random value - \param x the private random value - \param provider the provider to use, if a particular provider is - required - */ - DHPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider = QString()); - - /** - The discrete logarithm group that is being used - */ - DLGroup domain() const; - - /** - The public random value associated with this key - */ - BigInteger y() const; - - /** - The private random value associated with this key - */ - BigInteger x() const; + /** + Create an empty Diffie-Hellman private key + */ + DHPrivateKey(); + + /** + Create a Diffie-Hellman private key + + \param domain the discrete logarithm group to use + \param y the public random value + \param x the private random value + \param provider the provider to use, if a particular provider is + required + */ + DHPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider = QString()); + + /** + The discrete logarithm group that is being used + */ + DLGroup domain() const; + + /** + The public random value associated with this key + */ + BigInteger y() const; + + /** + The private random value associated with this key + */ + BigInteger x() const; }; /*@}*/ } diff --git a/include/QtCrypto/qca_safetimer.h b/include/QtCrypto/qca_safetimer.h --- a/include/QtCrypto/qca_safetimer.h +++ b/include/QtCrypto/qca_safetimer.h @@ -28,41 +28,42 @@ class QEvent; class QTimerEvent; -namespace QCA { +namespace QCA +{ class QCA_EXPORT SafeTimer : public QObject { - Q_OBJECT + Q_OBJECT public: - SafeTimer(QObject *parent = 0); - ~SafeTimer(); + SafeTimer(QObject *parent = 0); + ~SafeTimer(); - int interval() const; - bool isActive() const; - bool isSingleShot() const; - void setInterval(int msec); - void setSingleShot(bool singleShot); - int timerId() const; + int interval() const; + bool isActive() const; + bool isSingleShot() const; + void setInterval(int msec); + void setSingleShot(bool singleShot); + int timerId() const; public Q_SLOTS: - void start(int msec); - void start(); - void stop(); + void start(int msec); + void start(); + void stop(); Q_SIGNALS: - void timeout(); + void timeout(); protected: - bool event(QEvent *event); - void timerEvent(QTimerEvent *event); + bool event(QEvent *event); + void timerEvent(QTimerEvent *event); private: - // Functions is used internally. Outer world mustn't have access them. - void startTimer() {} - void killTimer(int) {} + // Functions is used internally. Outer world mustn't have access them. + void startTimer() {} + void killTimer(int) {} - class Private; - Private *d; + class Private; + Private *d; }; } diff --git a/include/QtCrypto/qca_securelayer.h b/include/QtCrypto/qca_securelayer.h --- a/include/QtCrypto/qca_securelayer.h +++ b/include/QtCrypto/qca_securelayer.h @@ -37,33 +37,33 @@ #include "qca_publickey.h" #include "qca_cert.h" -namespace QCA { +namespace QCA +{ /** Specify the lower-bound for acceptable TLS/SASL security layers For TLS, the interpretation of these levels is: - Any cipher suite that provides non-authenticated communications - (usually anonymous Diffie-Hellman) is SL_Integrity. + (usually anonymous Diffie-Hellman) is SL_Integrity. - Any cipher suite that is limited to 40 bits (export-version crippled forms of RC2, RC4 or DES) is SL_Export. Standard DES (56 bits) and some forms of RC4 (64 bits) are also SL_Export. - Any normal cipher (AES, Camellia, RC4 or similar) with 128 bits, or Elliptic Curve Ciphers with 283 bits, is SL_Baseline - AES or Camellia at least 192 bits, triple-DES and similar - ciphers are SL_High. ECC with 409 or more bits is also SL_High. + ciphers are SL_High. ECC with 409 or more bits is also SL_High. - Highest does not have an equivalent strength. It indicates that the provider should use the strongest - ciphers available (but not less than SL_High). + ciphers available (but not less than SL_High). */ -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 +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 }; /** @@ -103,128 +103,128 @@ */ class QCA_EXPORT SecureLayer : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Constructor for an abstract secure communications - layer - - \param parent the parent object for this object - */ - SecureLayer(QObject *parent = 0); - - /** - Returns true if the layer has a meaningful "close". - */ - virtual bool isClosable() const; - - /** - Returns the number of bytes available to be read() - on the application side. - */ - virtual int bytesAvailable() const = 0; - - /** - Returns the number of bytes available to be - readOutgoing() on the network side. - */ - virtual int bytesOutgoingAvailable() const = 0; - - /** - Close the link. Note that this may not be - meaningful / possible for all implementations. - - \sa isClosable() for a test that verifies if the - link can be %closed. - */ - virtual void close(); - - /** - This method writes unencrypted (plain) data to - the SecureLayer implementation. You normally - call this function on the application side. - - \param a the source of the application-side data - */ - virtual void write(const QByteArray &a) = 0; - - /** - This method reads decrypted (plain) data from - the SecureLayer implementation. You normally call - this function on the application side after receiving - the readyRead() signal. - */ - virtual QByteArray read() = 0; - - /** - This method accepts encoded (typically encrypted) data - for processing. You normally call this function using - data read from the network socket (e.g. using - QTcpSocket::readAll()) after receiving a signal that - indicates that the socket has data to read. - - \param a the ByteArray to take network-side data from - */ - virtual void writeIncoming(const QByteArray &a) = 0; - - /** - This method provides encoded (typically encrypted) - data. You normally call this function to get data - to write out to the network socket (e.g. using - QTcpSocket::write()) after receiving the - readyReadOutgoing() signal. - - \param plainBytes the number of bytes that were read. - */ - virtual QByteArray readOutgoing(int *plainBytes = 0) = 0; - - /** - This allows you to read data without having it - decrypted first. This is intended to be used for - protocols that close off the connection and return - to plain text transfer. You do not normally need to - use this function. - */ - virtual QByteArray readUnprocessed(); - - /** - Convert encrypted bytes written to plain text bytes written - - \param encryptedBytes the number of bytes to convert - */ - virtual int convertBytesWritten(qint64 encryptedBytes) = 0; + /** + Constructor for an abstract secure communications + layer + + \param parent the parent object for this object + */ + SecureLayer(QObject *parent = 0); + + /** + Returns true if the layer has a meaningful "close". + */ + virtual bool isClosable() const; + + /** + Returns the number of bytes available to be read() + on the application side. + */ + virtual int bytesAvailable() const = 0; + + /** + Returns the number of bytes available to be + readOutgoing() on the network side. + */ + virtual int bytesOutgoingAvailable() const = 0; + + /** + Close the link. Note that this may not be + meaningful / possible for all implementations. + + \sa isClosable() for a test that verifies if the + link can be %closed. + */ + virtual void close(); + + /** + This method writes unencrypted (plain) data to + the SecureLayer implementation. You normally + call this function on the application side. + + \param a the source of the application-side data + */ + virtual void write(const QByteArray &a) = 0; + + /** + This method reads decrypted (plain) data from + the SecureLayer implementation. You normally call + this function on the application side after receiving + the readyRead() signal. + */ + virtual QByteArray read() = 0; + + /** + This method accepts encoded (typically encrypted) data + for processing. You normally call this function using + data read from the network socket (e.g. using + QTcpSocket::readAll()) after receiving a signal that + indicates that the socket has data to read. + + \param a the ByteArray to take network-side data from + */ + virtual void writeIncoming(const QByteArray &a) = 0; + + /** + This method provides encoded (typically encrypted) + data. You normally call this function to get data + to write out to the network socket (e.g. using + QTcpSocket::write()) after receiving the + readyReadOutgoing() signal. + + \param plainBytes the number of bytes that were read. + */ + virtual QByteArray readOutgoing(int *plainBytes = 0) = 0; + + /** + This allows you to read data without having it + decrypted first. This is intended to be used for + protocols that close off the connection and return + to plain text transfer. You do not normally need to + use this function. + */ + virtual QByteArray readUnprocessed(); + + /** + Convert encrypted bytes written to plain text bytes written + + \param encryptedBytes the number of bytes to convert + */ + virtual int convertBytesWritten(qint64 encryptedBytes) = 0; Q_SIGNALS: - /** - This signal is emitted when SecureLayer has - decrypted (application side) data ready to be - read. Typically you will connect this signal to a - slot that reads the data (using read()). - */ - void readyRead(); - - /** - This signal is emitted when SecureLayer has encrypted - (network side) data ready to be read. Typically you - will connect this signal to a slot that reads the data - (using readOutgoing()) and writes it to a network socket. - */ - void readyReadOutgoing(); - - /** - This signal is emitted when the SecureLayer connection - is %closed. - */ - void closed(); - - /** - This signal is emitted when an error is detected. You - can determine the error type using errorCode(). - */ - void error(); + /** + This signal is emitted when SecureLayer has + decrypted (application side) data ready to be + read. Typically you will connect this signal to a + slot that reads the data (using read()). + */ + void readyRead(); + + /** + This signal is emitted when SecureLayer has encrypted + (network side) data ready to be read. Typically you + will connect this signal to a slot that reads the data + (using readOutgoing()) and writes it to a network socket. + */ + void readyReadOutgoing(); + + /** + This signal is emitted when the SecureLayer connection + is %closed. + */ + void closed(); + + /** + This signal is emitted when an error is detected. You + can determine the error type using errorCode(). + */ + void error(); private: - Q_DISABLE_COPY(SecureLayer) + Q_DISABLE_COPY(SecureLayer) }; /** @@ -238,34 +238,34 @@ class QCA_EXPORT TLSSession : public Algorithm { public: - TLSSession(); + TLSSession(); - /** - Copy constructor + /** + Copy constructor - \param from the session token to copy from - */ - TLSSession(const TLSSession &from); + \param from the session token to copy from + */ + TLSSession(const TLSSession &from); - ~TLSSession(); + ~TLSSession(); - /** - Assignment operator + /** + Assignment operator - \param from the session token to assign from - */ - TLSSession & operator=(const TLSSession &from); + \param from the session token to assign from + */ + TLSSession &operator=(const TLSSession &from); - /** - Test if the session token is valid - */ - bool isNull() const; + /** + Test if the session token is valid + */ + bool isNull() const; }; /** \class TLS qca_securelayer.h QtCrypto - Transport Layer Security / Secure Socket Layer + Transport Layer Security / Secure Socket Layer Transport Layer Security (%TLS) is the current state-of-the-art in secure transport mechanisms over the @@ -288,525 +288,521 @@ */ class QCA_EXPORT TLS : public SecureLayer, public Algorithm { - Q_OBJECT + Q_OBJECT public: - /** - Operating mode - */ - enum Mode - { - Stream, ///< stream mode - Datagram ///< datagram mode - }; - - /** - Version of %TLS or SSL - */ - enum Version - { - TLS_v1, ///< Transport Layer Security, version 1 - SSL_v3, ///< Secure Socket Layer, version 3 - SSL_v2, ///< Secure Socket Layer, version 2 - DTLS_v1 ///< Datagram Transport Layer Security, version 1 - }; - - /** - Type of error - */ - enum Error - { - ErrorSignerExpired, ///< local certificate is expired - ErrorSignerInvalid, ///< local certificate is invalid in some way - ErrorCertKeyMismatch, ///< certificate and private key don't match - ErrorInit, ///< problem starting up %TLS - ErrorHandshake, ///< problem during the negotiation - ErrorCrypt ///< problem at anytime after - }; - - /** - Type of identity - */ - enum IdentityResult - { - Valid, ///< identity is verified - HostMismatch, ///< valid cert provided, but wrong owner - InvalidCertificate, ///< invalid cert - NoCertificate ///< identity unknown - }; - - /** - Constructor for Transport Layer Security connection - - This produces a Stream (normal %TLS) rather than Datagram (DTLS) - object. - If you want to do DTLS, see below. - - \param parent the parent object for this object - \param provider the name of the provider, if a specific provider - is required - */ - explicit TLS(QObject *parent = 0, const QString &provider = QString()); - - /** - Constructor for Transport Layer Security connection. - - This constructor can be used for both normal %TLS (set mode to TLS::Stream) - or DTLS (set mode to TLS::Datagram). - - \param mode the connection Mode - \param parent the parent object for this object - \param provider the name of the provider, if a specific provider is - required - */ - explicit TLS(Mode mode, QObject *parent = 0, const QString &provider = QString()); - - /** - Destructor - */ - ~TLS(); - - /** - Reset the connection - */ - void reset(); - - /** - Get the list of cipher suites that are available for use. - - A cipher suite is a combination of key exchange, - encryption and hashing algorithms that are agreed - during the initial handshake between client and - server. - - \param version the protocol Version that the cipher - suites are required for - - \return list of the names of the cipher suites - supported. - */ - QStringList supportedCipherSuites(const Version &version = TLS_v1) const; - - /** - The local certificate to use. This is the - certificate that will be provided to the peer. This - is almost always required on the server side - (because the server has to provide a certificate to - the client), and may be used on the client side. - - \param cert a chain of certificates that - link the host certificate to a trusted root - certificate. - \param key the private key for the certificate - chain - */ - void setCertificate(const CertificateChain &cert, const PrivateKey &key); - - /** - \overload - - Allows setting a certificate from a KeyBundle. - - \param kb key bundle containing the local certificate - and associated private key. - */ - void setCertificate(const KeyBundle &kb); - - /** - Return the trusted certificates set for this object - */ - CertificateCollection trustedCertificates() const; - - /** - Set up the set of trusted certificates that will be used to verify - that the certificate provided is valid. - - Typically, this will be the collection of root certificates from - the system, which you can get using QCA::systemStore(), however you - may choose to pass whatever certificates match your assurance - needs. - - \param trusted a bundle of trusted certificates. - */ - void setTrustedCertificates(const CertificateCollection &trusted); - - /** - The security level required for this link - - \param s the level required for this link. - */ - void setConstraints(SecurityLevel s); - - /** - \overload - - \param minSSF the minimum Security Strength Factor - required for this link. - \param maxSSF the maximum Security Strength Factor - required for this link. - */ - void setConstraints(int minSSF, int maxSSF); - - /** - \overload - - \param cipherSuiteList a list of the names of - cipher suites that can be used for this link. - - \note the names are the same as the names in the - applicable IETF RFCs (or Internet Drafts if there - is no applicable RFC). - */ - void setConstraints(const QStringList &cipherSuiteList); - - /** - Retrieve the list of allowed issuers by the server, - if the server has provided them. Only DN types will - be present. - - \code -Certificate someCert = ... -PrivateKey someKey = ... - -// see if the server will take our cert -CertificateInfoOrdered issuerInfo = someCert.issuerInfoOrdered().dnOnly(); -foreach(const CertificateInfoOrdered &info, tls->issuerList()) -{ - if(info == issuerInfo) - { - // server will accept someCert, let's present it - tls->setCertificate(someCert, someKey); - break; - } -} - \endcode - */ - QList issuerList() const; - - /** - Sets the issuer list to present to the client. For - use with servers only. Only DN types are allowed. - - \param issuers the list of valid issuers to be used. - */ - void setIssuerList(const QList &issuers); - - /** - Resume a %TLS session using the given session object - - \param session the session state to use for resumption. - */ - void setSession(const TLSSession &session); - - /** - Test if the link can use compression - - \return true if the link can use compression - */ - bool canCompress() const; - - /** - Test if the link can specify a hostname (Server Name - Indication) - - \return true if the link can specify a hostname - */ - bool canSetHostName() const; - - /** - Returns true if compression is enabled - - This only indicates whether or not the object is configured to use - compression, not whether or not the link is actually compressed. - Use isCompressed() for that. - */ - bool compressionEnabled() const; - - /** - Set the link to use compression - - \param b true if the link should use compression, or false to - disable compression - */ - void setCompressionEnabled(bool b); - - /** - Returns the host name specified or an empty string if no host - name is specified. - */ - QString hostName() const; - - /** - Start the %TLS/SSL connection as a client - - Typically, you'll want to perform RFC 2818 validation on the - server's certificate, based on the hostname you're intending - to connect to. Pass a value for \a host in order to have the - validation for you. If you want to bypass this behavior and - do the validation yourself, pass an empty string for \a host. - - If the host is an internationalized domain name, then it must be - provided in unicode format, not in IDNA ACE/punycode format. - - \param host the hostname that you want to connect to - - \note The hostname will be used for Server Name Indication - extension (see - RFC 3546 Section - 3.1) if supported by the backend provider. - */ - void startClient(const QString &host = QString()); - - /** - Start the %TLS/SSL connection as a server. - */ - void startServer(); - - /** - Resumes %TLS processing. - - Call this function after hostNameReceived(), certificateRequested() - peerCertificateAvailable() or handshaken() is emitted. By - requiring this function to be called in order to proceed, - applications are given a chance to perform user interaction between - steps in the %TLS process. - */ - void continueAfterStep(); - - /** - test if the handshake is complete - - \return true if the handshake is complete - - \sa handshaken - */ - bool isHandshaken() const; - - /** - test if the link is compressed - - \return true if the link is compressed - */ - bool isCompressed() const; - - /** - The protocol version that is in use for this connection. - */ - Version version() const; - - /** - The cipher suite that has been negotiated for this connection. - - The name returned here is the name used in the applicable RFC - (or Internet Draft, where there is no RFC). - */ - QString cipherSuite() const; - - /** - The number of effective bits of security being used for this - connection. - - This can differ from the actual number of bits in - the cipher for certain - older "export ciphers" that are deliberately crippled. If you - want that information, use cipherMaxBits(). - */ - int cipherBits() const; - - /** - The number of bits of security that the cipher could use. - - This is normally the same as cipherBits(), but can be greater - for older "export ciphers". - */ - int cipherMaxBits() const; - - /** - The session object of the %TLS connection, which can be used - for resuming. - */ - TLSSession session() const; - - /** - This method returns the type of error that has - occurred. You should only need to check this if the - error() signal is emitted. - */ - Error errorCode() const; - - /** - After the SSL/%TLS handshake is complete, this - method allows you to determine if the other end - of the connection (if the application is a client, - this is the server; if the application is a server, - this is the client) has a valid identity. - - Note that the security of %TLS/SSL depends on - checking this. It is not enough to check that the - certificate is valid - you must check that the - certificate is valid for the entity that you are - trying to communicate with. - - \note If this returns QCA::TLS::InvalidCertificate, - you may wish to use peerCertificateValidity() to - determine whether to proceed or not. - */ - IdentityResult peerIdentityResult() const; - - /** - After the SSL/%TLS handshake is valid, this method - allows you to check if the received certificate - from the other end is valid. As noted in - peerIdentityResult(), you also need to check that - the certificate matches the entity you are trying - to communicate with. - */ - Validity peerCertificateValidity() const; - - /** - The CertificateChain for the local host - certificate. - */ - CertificateChain localCertificateChain() const; - - /** - The PrivateKey for the local host - certificate. - */ - PrivateKey localPrivateKey() const; - - /** - The CertificateChain from the peer (other end of - the connection to the trusted root certificate). - */ - CertificateChain peerCertificateChain() const; - - // reimplemented - virtual bool isClosable() const; - virtual int bytesAvailable() const; - virtual int bytesOutgoingAvailable() const; - virtual void close(); - virtual void write(const QByteArray &a); - virtual QByteArray read(); - virtual void writeIncoming(const QByteArray &a); - virtual QByteArray readOutgoing(int *plainBytes = 0); - virtual QByteArray readUnprocessed(); - virtual int convertBytesWritten(qint64 encryptedBytes); - - /** - Determine the number of packets available to be - read on the application side. - - \note this is only used with DTLS. - */ - int packetsAvailable() const; - - /** - Determine the number of packets available to be - read on the network side. - - \note this is only used with DTLS. - */ - int packetsOutgoingAvailable() const; - - /** - Return the currently configured maximum packet size - - \note this is only used with DTLS - */ - int packetMTU() const; - - /** - Set the maximum packet size to use. - - \param size the number of bytes to set as the MTU. - - \note this is only used with DTLS. - */ - void setPacketMTU(int size) const; + /** + Operating mode + */ + enum Mode { + Stream, ///< stream mode + Datagram ///< datagram mode + }; + + /** + Version of %TLS or SSL + */ + enum Version { + TLS_v1, ///< Transport Layer Security, version 1 + SSL_v3, ///< Secure Socket Layer, version 3 + SSL_v2, ///< Secure Socket Layer, version 2 + DTLS_v1 ///< Datagram Transport Layer Security, version 1 + }; + + /** + Type of error + */ + enum Error { + ErrorSignerExpired, ///< local certificate is expired + ErrorSignerInvalid, ///< local certificate is invalid in some way + ErrorCertKeyMismatch, ///< certificate and private key don't match + ErrorInit, ///< problem starting up %TLS + ErrorHandshake, ///< problem during the negotiation + ErrorCrypt ///< problem at anytime after + }; + + /** + Type of identity + */ + enum IdentityResult { + Valid, ///< identity is verified + HostMismatch, ///< valid cert provided, but wrong owner + InvalidCertificate, ///< invalid cert + NoCertificate ///< identity unknown + }; + + /** + Constructor for Transport Layer Security connection + + This produces a Stream (normal %TLS) rather than Datagram (DTLS) + object. + If you want to do DTLS, see below. + + \param parent the parent object for this object + \param provider the name of the provider, if a specific provider + is required + */ + explicit TLS(QObject *parent = 0, const QString &provider = QString()); + + /** + Constructor for Transport Layer Security connection. + + This constructor can be used for both normal %TLS (set mode to TLS::Stream) + or DTLS (set mode to TLS::Datagram). + + \param mode the connection Mode + \param parent the parent object for this object + \param provider the name of the provider, if a specific provider is + required + */ + explicit TLS(Mode mode, QObject *parent = 0, const QString &provider = QString()); + + /** + Destructor + */ + ~TLS(); + + /** + Reset the connection + */ + void reset(); + + /** + Get the list of cipher suites that are available for use. + + A cipher suite is a combination of key exchange, + encryption and hashing algorithms that are agreed + during the initial handshake between client and + server. + + \param version the protocol Version that the cipher + suites are required for + + \return list of the names of the cipher suites + supported. + */ + QStringList supportedCipherSuites(const Version &version = TLS_v1) const; + + /** + The local certificate to use. This is the + certificate that will be provided to the peer. This + is almost always required on the server side + (because the server has to provide a certificate to + the client), and may be used on the client side. + + \param cert a chain of certificates that + link the host certificate to a trusted root + certificate. + \param key the private key for the certificate + chain + */ + void setCertificate(const CertificateChain &cert, const PrivateKey &key); + + /** + \overload + + Allows setting a certificate from a KeyBundle. + + \param kb key bundle containing the local certificate + and associated private key. + */ + void setCertificate(const KeyBundle &kb); + + /** + Return the trusted certificates set for this object + */ + CertificateCollection trustedCertificates() const; + + /** + Set up the set of trusted certificates that will be used to verify + that the certificate provided is valid. + + Typically, this will be the collection of root certificates from + the system, which you can get using QCA::systemStore(), however you + may choose to pass whatever certificates match your assurance + needs. + + \param trusted a bundle of trusted certificates. + */ + void setTrustedCertificates(const CertificateCollection &trusted); + + /** + The security level required for this link + + \param s the level required for this link. + */ + void setConstraints(SecurityLevel s); + + /** + \overload + + \param minSSF the minimum Security Strength Factor + required for this link. + \param maxSSF the maximum Security Strength Factor + required for this link. + */ + void setConstraints(int minSSF, int maxSSF); + + /** + \overload + + \param cipherSuiteList a list of the names of + cipher suites that can be used for this link. + + \note the names are the same as the names in the + applicable IETF RFCs (or Internet Drafts if there + is no applicable RFC). + */ + void setConstraints(const QStringList &cipherSuiteList); + + /** + Retrieve the list of allowed issuers by the server, + if the server has provided them. Only DN types will + be present. + + \code + Certificate someCert = ... + PrivateKey someKey = ... + + // see if the server will take our cert + CertificateInfoOrdered issuerInfo = someCert.issuerInfoOrdered().dnOnly(); + foreach(const CertificateInfoOrdered &info, tls->issuerList()) + { + if(info == issuerInfo) + { + // server will accept someCert, let's present it + tls->setCertificate(someCert, someKey); + break; + } + } + \endcode + */ + QList issuerList() const; + + /** + Sets the issuer list to present to the client. For + use with servers only. Only DN types are allowed. + + \param issuers the list of valid issuers to be used. + */ + void setIssuerList(const QList &issuers); + + /** + Resume a %TLS session using the given session object + + \param session the session state to use for resumption. + */ + void setSession(const TLSSession &session); + + /** + Test if the link can use compression + + \return true if the link can use compression + */ + bool canCompress() const; + + /** + Test if the link can specify a hostname (Server Name + Indication) + + \return true if the link can specify a hostname + */ + bool canSetHostName() const; + + /** + Returns true if compression is enabled + + This only indicates whether or not the object is configured to use + compression, not whether or not the link is actually compressed. + Use isCompressed() for that. + */ + bool compressionEnabled() const; + + /** + Set the link to use compression + + \param b true if the link should use compression, or false to + disable compression + */ + void setCompressionEnabled(bool b); + + /** + Returns the host name specified or an empty string if no host + name is specified. + */ + QString hostName() const; + + /** + Start the %TLS/SSL connection as a client + + Typically, you'll want to perform RFC 2818 validation on the + server's certificate, based on the hostname you're intending + to connect to. Pass a value for \a host in order to have the + validation for you. If you want to bypass this behavior and + do the validation yourself, pass an empty string for \a host. + + If the host is an internationalized domain name, then it must be + provided in unicode format, not in IDNA ACE/punycode format. + + \param host the hostname that you want to connect to + + \note The hostname will be used for Server Name Indication + extension (see + RFC 3546 Section + 3.1) if supported by the backend provider. + */ + void startClient(const QString &host = QString()); + + /** + Start the %TLS/SSL connection as a server. + */ + void startServer(); + + /** + Resumes %TLS processing. + + Call this function after hostNameReceived(), certificateRequested() + peerCertificateAvailable() or handshaken() is emitted. By + requiring this function to be called in order to proceed, + applications are given a chance to perform user interaction between + steps in the %TLS process. + */ + void continueAfterStep(); + + /** + test if the handshake is complete + + \return true if the handshake is complete + + \sa handshaken + */ + bool isHandshaken() const; + + /** + test if the link is compressed + + \return true if the link is compressed + */ + bool isCompressed() const; + + /** + The protocol version that is in use for this connection. + */ + Version version() const; + + /** + The cipher suite that has been negotiated for this connection. + + The name returned here is the name used in the applicable RFC + (or Internet Draft, where there is no RFC). + */ + QString cipherSuite() const; + + /** + The number of effective bits of security being used for this + connection. + + This can differ from the actual number of bits in + the cipher for certain + older "export ciphers" that are deliberately crippled. If you + want that information, use cipherMaxBits(). + */ + int cipherBits() const; + + /** + The number of bits of security that the cipher could use. + + This is normally the same as cipherBits(), but can be greater + for older "export ciphers". + */ + int cipherMaxBits() const; + + /** + The session object of the %TLS connection, which can be used + for resuming. + */ + TLSSession session() const; + + /** + This method returns the type of error that has + occurred. You should only need to check this if the + error() signal is emitted. + */ + Error errorCode() const; + + /** + After the SSL/%TLS handshake is complete, this + method allows you to determine if the other end + of the connection (if the application is a client, + this is the server; if the application is a server, + this is the client) has a valid identity. + + Note that the security of %TLS/SSL depends on + checking this. It is not enough to check that the + certificate is valid - you must check that the + certificate is valid for the entity that you are + trying to communicate with. + + \note If this returns QCA::TLS::InvalidCertificate, + you may wish to use peerCertificateValidity() to + determine whether to proceed or not. + */ + IdentityResult peerIdentityResult() const; + + /** + After the SSL/%TLS handshake is valid, this method + allows you to check if the received certificate + from the other end is valid. As noted in + peerIdentityResult(), you also need to check that + the certificate matches the entity you are trying + to communicate with. + */ + Validity peerCertificateValidity() const; + + /** + The CertificateChain for the local host + certificate. + */ + CertificateChain localCertificateChain() const; + + /** + The PrivateKey for the local host + certificate. + */ + PrivateKey localPrivateKey() const; + + /** + The CertificateChain from the peer (other end of + the connection to the trusted root certificate). + */ + CertificateChain peerCertificateChain() const; + + // reimplemented + virtual bool isClosable() const; + virtual int bytesAvailable() const; + virtual int bytesOutgoingAvailable() const; + virtual void close(); + virtual void write(const QByteArray &a); + virtual QByteArray read(); + virtual void writeIncoming(const QByteArray &a); + virtual QByteArray readOutgoing(int *plainBytes = 0); + virtual QByteArray readUnprocessed(); + virtual int convertBytesWritten(qint64 encryptedBytes); + + /** + Determine the number of packets available to be + read on the application side. + + \note this is only used with DTLS. + */ + int packetsAvailable() const; + + /** + Determine the number of packets available to be + read on the network side. + + \note this is only used with DTLS. + */ + int packetsOutgoingAvailable() const; + + /** + Return the currently configured maximum packet size + + \note this is only used with DTLS + */ + int packetMTU() const; + + /** + Set the maximum packet size to use. + + \param size the number of bytes to set as the MTU. + + \note this is only used with DTLS. + */ + void setPacketMTU(int size) const; Q_SIGNALS: - /** - Emitted if a host name is set by the client. At - this time, the server can inspect the hostName(). + /** + Emitted if a host name is set by the client. At + this time, the server can inspect the hostName(). - You must call continueAfterStep() in order for %TLS - processing to resume after this signal is emitted. + You must call continueAfterStep() in order for %TLS + processing to resume after this signal is emitted. - This signal is only emitted in server mode. + This signal is only emitted in server mode. - \sa continueAfterStep - */ - void hostNameReceived(); + \sa continueAfterStep + */ + void hostNameReceived(); - /** - Emitted when the server requests a certificate. At - this time, the client can inspect the issuerList(). + /** + Emitted when the server requests a certificate. At + this time, the client can inspect the issuerList(). - You must call continueAfterStep() in order for %TLS - processing to resume after this signal is emitted. + You must call continueAfterStep() in order for %TLS + processing to resume after this signal is emitted. - This signal is only emitted in client mode. + This signal is only emitted in client mode. - \sa continueAfterStep - */ - void certificateRequested(); + \sa continueAfterStep + */ + void certificateRequested(); - /** - Emitted when a certificate is received from the peer. - At this time, you may inspect peerIdentityResult(), - peerCertificateValidity(), and peerCertificateChain(). + /** + Emitted when a certificate is received from the peer. + At this time, you may inspect peerIdentityResult(), + peerCertificateValidity(), and peerCertificateChain(). - You must call continueAfterStep() in order for %TLS - processing to resume after this signal is emitted. + You must call continueAfterStep() in order for %TLS + processing to resume after this signal is emitted. - \sa continueAfterStep - */ - void peerCertificateAvailable(); + \sa continueAfterStep + */ + void peerCertificateAvailable(); - /** - Emitted when the protocol handshake is complete. At - this time, all available information about the %TLS - session can be inspected. + /** + Emitted when the protocol handshake is complete. At + this time, all available information about the %TLS + session can be inspected. - You must call continueAfterStep() in order for %TLS - processing to resume after this signal is emitted. + You must call continueAfterStep() in order for %TLS + processing to resume after this signal is emitted. - \sa continueAfterStep - \sa isHandshaken - */ - void handshaken(); + \sa continueAfterStep + \sa isHandshaken + */ + void handshaken(); protected: - /** - Called when a connection is made to a particular signal + /** + Called when a connection is made to a particular signal - \param signal the name of the signal that has been - connected to. - */ + \param signal the name of the signal that has been + connected to. + */ #if QT_VERSION >= 0x050000 - void connectNotify(const QMetaMethod &signal); + void connectNotify(const QMetaMethod &signal); #else - void connectNotify(const char *signal); + void connectNotify(const char *signal); #endif - /** - Called when a connection is removed from a particular signal + /** + Called when a connection is removed from a particular signal - \param signal the name of the signal that has been - disconnected from. - */ + \param signal the name of the signal that has been + disconnected from. + */ #if QT_VERSION >= 0x050000 - void disconnectNotify(const QMetaMethod &signal); + void disconnectNotify(const QMetaMethod &signal); #else - void disconnectNotify(const char *signal); + void disconnectNotify(const char *signal); #endif private: - Q_DISABLE_COPY(TLS) + Q_DISABLE_COPY(TLS) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -838,417 +834,412 @@ */ class QCA_EXPORT SASL : public SecureLayer, public Algorithm { - Q_OBJECT + Q_OBJECT public: - /** - Possible errors that may occur when using %SASL - */ - enum Error - { - ErrorInit, ///< problem starting up %SASL - ErrorHandshake, ///< problem during the authentication process - ErrorCrypt ///< problem at anytime after - }; - - /** - Possible authentication error states - */ - enum AuthCondition - { - AuthFail, ///< Generic authentication failure - NoMechanism, ///< No compatible/appropriate authentication mechanism - BadProtocol, ///< Bad protocol or cancelled - BadServer, ///< Server failed mutual authentication (client side only) - BadAuth, ///< Authentication failure (server side only) - NoAuthzid, ///< Authorization failure (server side only) - TooWeak, ///< Mechanism too weak for this user (server side only) - NeedEncrypt, ///< Encryption is needed in order to use mechanism (server side only) - Expired, ///< Passphrase expired, has to be reset (server side only) - Disabled, ///< Account is disabled (server side only) - NoUser, ///< User not found (server side only) - RemoteUnavailable ///< Remote service needed for auth is gone (server side only) - }; - - /** - Authentication requirement flag values - */ - enum AuthFlags - { - AuthFlagsNone = 0x00, - AllowPlain = 0x01, - AllowAnonymous = 0x02, - RequireForwardSecrecy = 0x04, - RequirePassCredentials = 0x08, - RequireMutualAuth = 0x10, - RequireAuthzidSupport = 0x20 // server-only - }; - - /** - Mode options for client side sending - */ - enum ClientSendMode - { - AllowClientSendFirst, - DisableClientSendFirst - }; - - /** - Mode options for server side sending - */ - enum ServerSendMode - { - AllowServerSendLast, - DisableServerSendLast - }; - - /** - \class Params qca_securelayer.h QtCrypto - - Parameter flags for the %SASL authentication - - This is used to indicate which parameters are needed by %SASL - in order to complete the authentication process. - - \ingroup UserAPI - */ - class QCA_EXPORT Params - { - public: - Params(); - - /** - Standard constructor. - - The concept behind this is that you set each of the - flags depending on which parameters are needed. - - \param user the username is required - \param authzid the authorization identity is required - \param pass the password is required - \param realm the realm is required - */ - Params(bool user, bool authzid, bool pass, bool realm); - - /** - Standard copy constructor - - \param from the Params object to copy - */ - Params(const Params &from); - ~Params(); - - /** - Standard assignment operator - - \param from the Params object to assign from - */ - Params & operator=(const Params &from); - - /** - User is needed - */ - bool needUsername() const; - - /** - An Authorization ID can be sent if desired - */ - bool canSendAuthzid() const; - - /** - Password is needed - */ - bool needPassword() const; - - /** - A Realm can be sent if desired - */ - bool canSendRealm() const; - - private: - class Private; - Private *d; - }; - - /** - Standard constructor - - \param parent the parent object for this %SASL connection - \param provider if specified, the provider to use. If not - specified, or specified as empty, then any provider is - acceptable. - */ - explicit SASL(QObject *parent = 0, const QString &provider = QString()); - - ~SASL(); - - /** - Reset the %SASL mechanism - */ - void reset(); - - /** - Specify connection constraints - - %SASL supports a range of authentication requirements, and - a range of security levels. This method allows you to - specify the requirements for your connection. - - \param f the authentication requirements, which you typically - build using a binary OR function (eg AllowPlain | AllowAnonymous) - \param s the security level of the encryption, if used. See - SecurityLevel for details of what each level provides. - */ - void setConstraints(AuthFlags f, SecurityLevel s = SL_None); - - /** - \overload - - Unless you have a specific reason for directly specifying a - strength factor, you probably should use the method above. - - \param f the authentication requirements, which you typically - build using a binary OR function (eg AllowPlain | AllowAnonymous) - \param minSSF the minimum security strength factor that is required - \param maxSSF the maximum security strength factor that is required - - \note Security strength factors are a rough approximation to key - length in the encryption function (eg if you are securing with - plain DES, the security strength factor would be 56). - */ - void setConstraints(AuthFlags f, int minSSF, int maxSSF); - - /** - Specify the local address. - - \param addr the address of the local part of the connection - \param port the port number of the local part of the connection - */ - void setLocalAddress(const QString &addr, quint16 port); - - /** - Specify the peer address. - - \param addr the address of the peer side of the connection - \param port the port number of the peer side of the connection - */ - void setRemoteAddress(const QString &addr, quint16 port); - - /** - Specify the id of the externally secured connection - - \param authid the id of the connection - */ - void setExternalAuthId(const QString &authid); - - /** - Specify a security strength factor for an externally secured - connection - - \param strength the security strength factor of the connection - */ - void setExternalSSF(int strength); - - /** - Initialise the client side of the connection - - startClient must be called on the client side of the connection. - clientStarted will be emitted when the operation is completed. - - \param service the name of the service - \param host the client side host name - \param mechlist the list of mechanisms which can be used - \param mode the mode to use on the client side - */ - void startClient(const QString &service, const QString &host, const QStringList &mechlist, ClientSendMode mode = AllowClientSendFirst); - - /** - Initialise the server side of the connection - - startServer must be called on the server side of the connection. - serverStarted will be emitted when the operation is completed. - - \param service the name of the service - \param host the server side host name - \param realm the realm to use - \param mode which mode to use on the server side - */ - void startServer(const QString &service, const QString &host, const QString &realm, ServerSendMode mode = DisableServerSendLast); - - /** - Process the first step in server mode (server) - - Call this with the mechanism selected by the client. If there - is initial client data, call the other version of this function - instead. - - \param mech the mechanism to be used. - */ - void putServerFirstStep(const QString &mech); - - /** - Process the first step in server mode (server) - - Call this with the mechanism selected by the client, and initial - client data. If there is no initial client data, call the other - version of this function instead. - - \param mech the mechanism to be used - \param clientInit the initial data provided by the client side - */ - void putServerFirstStep(const QString &mech, const QByteArray &clientInit); - - /** - Process an authentication step - - Call this with authentication data received from the network. - The only exception is the first step in server mode, in which - case putServerFirstStep must be called. - - \param stepData the authentication data from the network - */ - void putStep(const QByteArray &stepData); - - /** - Return the mechanism selected (client) - */ - QString mechanism() const; - - /** - Return the mechanism list (server) - */ - QStringList mechanismList() const; - - /** - Return the realm list, if available (client) - */ - QStringList realmList() const; - - /** - Return the security strength factor of the connection - */ - int ssf() const; - - /** - Return the error code - */ - Error errorCode() const; - - /** - Return the reason for authentication failure - */ - AuthCondition authCondition() const; - - /** - Specify the username to use in authentication - - \param user the username to use - */ - void setUsername(const QString &user); - - /** - Specify the authorization identity to use in authentication - - \param auth the authorization identity to use - */ - void setAuthzid(const QString &auth); - - /** - Specify the password to use in authentication - - \param pass the password to use - */ - void setPassword(const SecureArray &pass); - - /** - Specify the realm to use in authentication - - \param realm the realm to use - */ - void setRealm(const QString &realm); - - /** - Continue negotiation after parameters have been set (client) - */ - void continueAfterParams(); - - /** - Continue negotiation after auth ids have been checked (server) - */ - void continueAfterAuthCheck(); - - // reimplemented - virtual int bytesAvailable() const; - virtual int bytesOutgoingAvailable() const; - virtual void write(const QByteArray &a); - virtual QByteArray read(); - virtual void writeIncoming(const QByteArray &a); - virtual QByteArray readOutgoing(int *plainBytes = 0); - virtual int convertBytesWritten(qint64 encryptedBytes); + /** + Possible errors that may occur when using %SASL + */ + enum Error { + ErrorInit, ///< problem starting up %SASL + ErrorHandshake, ///< problem during the authentication process + ErrorCrypt ///< problem at anytime after + }; + + /** + Possible authentication error states + */ + enum AuthCondition { + AuthFail, ///< Generic authentication failure + NoMechanism, ///< No compatible/appropriate authentication mechanism + BadProtocol, ///< Bad protocol or cancelled + BadServer, ///< Server failed mutual authentication (client side only) + BadAuth, ///< Authentication failure (server side only) + NoAuthzid, ///< Authorization failure (server side only) + TooWeak, ///< Mechanism too weak for this user (server side only) + NeedEncrypt, ///< Encryption is needed in order to use mechanism (server side only) + Expired, ///< Passphrase expired, has to be reset (server side only) + Disabled, ///< Account is disabled (server side only) + NoUser, ///< User not found (server side only) + RemoteUnavailable ///< Remote service needed for auth is gone (server side only) + }; + + /** + Authentication requirement flag values + */ + enum AuthFlags { + AuthFlagsNone = 0x00, + AllowPlain = 0x01, + AllowAnonymous = 0x02, + RequireForwardSecrecy = 0x04, + RequirePassCredentials = 0x08, + RequireMutualAuth = 0x10, + RequireAuthzidSupport = 0x20 // server-only + }; + + /** + Mode options for client side sending + */ + enum ClientSendMode { + AllowClientSendFirst, + DisableClientSendFirst + }; + + /** + Mode options for server side sending + */ + enum ServerSendMode { + AllowServerSendLast, + DisableServerSendLast + }; + + /** + \class Params qca_securelayer.h QtCrypto + + Parameter flags for the %SASL authentication + + This is used to indicate which parameters are needed by %SASL + in order to complete the authentication process. + + \ingroup UserAPI + */ + class QCA_EXPORT Params + { + public: + Params(); + + /** + Standard constructor. + + The concept behind this is that you set each of the + flags depending on which parameters are needed. + + \param user the username is required + \param authzid the authorization identity is required + \param pass the password is required + \param realm the realm is required + */ + Params(bool user, bool authzid, bool pass, bool realm); + + /** + Standard copy constructor + + \param from the Params object to copy + */ + Params(const Params &from); + ~Params(); + + /** + Standard assignment operator + + \param from the Params object to assign from + */ + Params &operator=(const Params &from); + + /** + User is needed + */ + bool needUsername() const; + + /** + An Authorization ID can be sent if desired + */ + bool canSendAuthzid() const; + + /** + Password is needed + */ + bool needPassword() const; + + /** + A Realm can be sent if desired + */ + bool canSendRealm() const; + + private: + class Private; + Private *d; + }; + + /** + Standard constructor + + \param parent the parent object for this %SASL connection + \param provider if specified, the provider to use. If not + specified, or specified as empty, then any provider is + acceptable. + */ + explicit SASL(QObject *parent = 0, const QString &provider = QString()); + + ~SASL(); + + /** + Reset the %SASL mechanism + */ + void reset(); + + /** + Specify connection constraints + + %SASL supports a range of authentication requirements, and + a range of security levels. This method allows you to + specify the requirements for your connection. + + \param f the authentication requirements, which you typically + build using a binary OR function (eg AllowPlain | AllowAnonymous) + \param s the security level of the encryption, if used. See + SecurityLevel for details of what each level provides. + */ + void setConstraints(AuthFlags f, SecurityLevel s = SL_None); + + /** + \overload + + Unless you have a specific reason for directly specifying a + strength factor, you probably should use the method above. + + \param f the authentication requirements, which you typically + build using a binary OR function (eg AllowPlain | AllowAnonymous) + \param minSSF the minimum security strength factor that is required + \param maxSSF the maximum security strength factor that is required + + \note Security strength factors are a rough approximation to key + length in the encryption function (eg if you are securing with + plain DES, the security strength factor would be 56). + */ + void setConstraints(AuthFlags f, int minSSF, int maxSSF); + + /** + Specify the local address. + + \param addr the address of the local part of the connection + \param port the port number of the local part of the connection + */ + void setLocalAddress(const QString &addr, quint16 port); + + /** + Specify the peer address. + + \param addr the address of the peer side of the connection + \param port the port number of the peer side of the connection + */ + void setRemoteAddress(const QString &addr, quint16 port); + + /** + Specify the id of the externally secured connection + + \param authid the id of the connection + */ + void setExternalAuthId(const QString &authid); + + /** + Specify a security strength factor for an externally secured + connection + + \param strength the security strength factor of the connection + */ + void setExternalSSF(int strength); + + /** + Initialise the client side of the connection + + startClient must be called on the client side of the connection. + clientStarted will be emitted when the operation is completed. + + \param service the name of the service + \param host the client side host name + \param mechlist the list of mechanisms which can be used + \param mode the mode to use on the client side + */ + void startClient(const QString &service, const QString &host, const QStringList &mechlist, ClientSendMode mode = AllowClientSendFirst); + + /** + Initialise the server side of the connection + + startServer must be called on the server side of the connection. + serverStarted will be emitted when the operation is completed. + + \param service the name of the service + \param host the server side host name + \param realm the realm to use + \param mode which mode to use on the server side + */ + void startServer(const QString &service, const QString &host, const QString &realm, ServerSendMode mode = DisableServerSendLast); + + /** + Process the first step in server mode (server) + + Call this with the mechanism selected by the client. If there + is initial client data, call the other version of this function + instead. + + \param mech the mechanism to be used. + */ + void putServerFirstStep(const QString &mech); + + /** + Process the first step in server mode (server) + + Call this with the mechanism selected by the client, and initial + client data. If there is no initial client data, call the other + version of this function instead. + + \param mech the mechanism to be used + \param clientInit the initial data provided by the client side + */ + void putServerFirstStep(const QString &mech, const QByteArray &clientInit); + + /** + Process an authentication step + + Call this with authentication data received from the network. + The only exception is the first step in server mode, in which + case putServerFirstStep must be called. + + \param stepData the authentication data from the network + */ + void putStep(const QByteArray &stepData); + + /** + Return the mechanism selected (client) + */ + QString mechanism() const; + + /** + Return the mechanism list (server) + */ + QStringList mechanismList() const; + + /** + Return the realm list, if available (client) + */ + QStringList realmList() const; + + /** + Return the security strength factor of the connection + */ + int ssf() const; + + /** + Return the error code + */ + Error errorCode() const; + + /** + Return the reason for authentication failure + */ + AuthCondition authCondition() const; + + /** + Specify the username to use in authentication + + \param user the username to use + */ + void setUsername(const QString &user); + + /** + Specify the authorization identity to use in authentication + + \param auth the authorization identity to use + */ + void setAuthzid(const QString &auth); + + /** + Specify the password to use in authentication + + \param pass the password to use + */ + void setPassword(const SecureArray &pass); + + /** + Specify the realm to use in authentication + + \param realm the realm to use + */ + void setRealm(const QString &realm); + + /** + Continue negotiation after parameters have been set (client) + */ + void continueAfterParams(); + + /** + Continue negotiation after auth ids have been checked (server) + */ + void continueAfterAuthCheck(); + + // reimplemented + virtual int bytesAvailable() const; + virtual int bytesOutgoingAvailable() const; + virtual void write(const QByteArray &a); + virtual QByteArray read(); + virtual void writeIncoming(const QByteArray &a); + virtual QByteArray readOutgoing(int *plainBytes = 0); + virtual int convertBytesWritten(qint64 encryptedBytes); Q_SIGNALS: - /** - This signal is emitted when the client has been successfully - started - - \param clientInit true if the client should send an initial - response to the server - \param clientInitData the initial response to send to the server. - Do note that there is a difference in SASL between an empty initial - response and no initial response, and so even if clientInitData is - an empty array, you still need to send an initial response if - clientInit is true. - */ - void clientStarted(bool clientInit, const QByteArray &clientInitData); - - /** - This signal is emitted after the server has been - successfully started - */ - void serverStarted(); - - /** - This signal is emitted when there is data required - to be sent over the network to complete the next - step in the authentication process. - - \param stepData the data to send over the network - */ - void nextStep(const QByteArray &stepData); - - /** - This signal is emitted when the client needs - additional parameters - - After receiving this signal, the application should set - the required parameter values appropriately and then call - continueAfterParams(). - - \param params the parameters that are required by the client - */ - void needParams(const QCA::SASL::Params ¶ms); - - /** - This signal is emitted when the server needs to - perform the authentication check - - If the user and authzid are valid, call continueAfterAuthCheck(). - - \param user the user identification name - \param authzid the user authorization name - */ - void authCheck(const QString &user, const QString &authzid); - - /** - This signal is emitted when authentication is complete. - */ - void authenticated(); + /** + This signal is emitted when the client has been successfully + started + + \param clientInit true if the client should send an initial + response to the server + \param clientInitData the initial response to send to the server. + Do note that there is a difference in SASL between an empty initial + response and no initial response, and so even if clientInitData is + an empty array, you still need to send an initial response if + clientInit is true. + */ + void clientStarted(bool clientInit, const QByteArray &clientInitData); + + /** + This signal is emitted after the server has been + successfully started + */ + void serverStarted(); + + /** + This signal is emitted when there is data required + to be sent over the network to complete the next + step in the authentication process. + + \param stepData the data to send over the network + */ + void nextStep(const QByteArray &stepData); + + /** + This signal is emitted when the client needs + additional parameters + + After receiving this signal, the application should set + the required parameter values appropriately and then call + continueAfterParams(). + + \param params the parameters that are required by the client + */ + void needParams(const QCA::SASL::Params ¶ms); + + /** + This signal is emitted when the server needs to + perform the authentication check + + If the user and authzid are valid, call continueAfterAuthCheck(). + + \param user the user identification name + \param authzid the user authorization name + */ + void authCheck(const QString &user, const QString &authzid); + + /** + This signal is emitted when authentication is complete. + */ + void authenticated(); private: - Q_DISABLE_COPY(SASL) + Q_DISABLE_COPY(SASL) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; } diff --git a/include/QtCrypto/qca_securemessage.h b/include/QtCrypto/qca_securemessage.h --- a/include/QtCrypto/qca_securemessage.h +++ b/include/QtCrypto/qca_securemessage.h @@ -40,7 +40,8 @@ class QDateTime; -namespace QCA { +namespace QCA +{ class SecureMessageSystem; @@ -54,119 +55,118 @@ class QCA_EXPORT SecureMessageKey { public: - /** - The key type - */ - enum Type - { - None, ///< no key - PGP, ///< Pretty Good Privacy key - X509 ///< X.509 CMS key - }; + /** + The key type + */ + enum Type { + None, ///< no key + PGP, ///< Pretty Good Privacy key + X509 ///< X.509 CMS key + }; - /** - Construct an empty key - */ - SecureMessageKey(); + /** + Construct an empty key + */ + SecureMessageKey(); - /** - Standard copy constructor + /** + Standard copy constructor - \param from the source key - */ - SecureMessageKey(const SecureMessageKey &from); + \param from the source key + */ + SecureMessageKey(const SecureMessageKey &from); - ~SecureMessageKey(); + ~SecureMessageKey(); - /** - Standard assignment operator + /** + Standard assignment operator - \param from the source key - */ - SecureMessageKey & operator=(const SecureMessageKey &from); + \param from the source key + */ + SecureMessageKey &operator=(const SecureMessageKey &from); - /** - Returns true for null object - */ - bool isNull() const; + /** + Returns true for null object + */ + bool isNull() const; - /** - The key type - */ - Type type() const; + /** + The key type + */ + Type type() const; - /** - Public key part of a PGP key - */ - PGPKey pgpPublicKey() const; + /** + Public key part of a PGP key + */ + PGPKey pgpPublicKey() const; - /** - Private key part of a PGP key - */ - PGPKey pgpSecretKey() const; + /** + Private key part of a PGP key + */ + PGPKey pgpSecretKey() const; - /** - Set the public key part of a PGP key + /** + Set the public key part of a PGP key - \param pub the PGP public key - */ - void setPGPPublicKey(const PGPKey &pub); + \param pub the PGP public key + */ + void setPGPPublicKey(const PGPKey &pub); - /** - Set the private key part of a PGP key + /** + Set the private key part of a PGP key - \param sec the PGP secretkey - */ - void setPGPSecretKey(const PGPKey &sec); + \param sec the PGP secretkey + */ + void setPGPSecretKey(const PGPKey &sec); - /** - The X.509 certificate chain (public part) for this key - */ - CertificateChain x509CertificateChain() const; + /** + The X.509 certificate chain (public part) for this key + */ + CertificateChain x509CertificateChain() const; - /** - The X.509 private key part of this key - */ - PrivateKey x509PrivateKey() const; + /** + The X.509 private key part of this key + */ + PrivateKey x509PrivateKey() const; - /** - Set the public key part of this X.509 key. + /** + Set the public key part of this X.509 key. - \param c the Certificate chain containing the public keys - */ - void setX509CertificateChain(const CertificateChain &c); + \param c the Certificate chain containing the public keys + */ + void setX509CertificateChain(const CertificateChain &c); - /** - Set the private key part of this X.509 key. + /** + Set the private key part of this X.509 key. - \param k the private key - */ - void setX509PrivateKey(const PrivateKey &k); + \param k the private key + */ + void setX509PrivateKey(const PrivateKey &k); - /** - Set the public and private part of this X.509 key with KeyBundle. + /** + Set the public and private part of this X.509 key with KeyBundle. - \param kb the public and private key bundle - */ - void setX509KeyBundle(const KeyBundle &kb); + \param kb the public and private key bundle + */ + void setX509KeyBundle(const KeyBundle &kb); - /** - Test if this key contains a private key part - */ - bool havePrivate() const; + /** + Test if this key contains a private key part + */ + bool havePrivate() const; - /** - The name associated with this key + /** + The name associated with this key - For a PGP key, this is the primary user ID + For a PGP key, this is the primary user ID - For an X.509 key, this is the Common Name - */ - QString name() const; + For an X.509 key, this is the Common Name + */ + QString name() const; private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** @@ -184,85 +184,83 @@ class QCA_EXPORT SecureMessageSignature { public: - /** - The result of identity verification - */ - enum IdentityResult - { - Valid, ///< indentity is verified, matches signature - InvalidSignature, ///< valid key provided, but signature failed - InvalidKey, ///< invalid key provided - NoKey ///< identity unknown - }; - - /** - Create an empty signature check object. - - User applications don't normally need to create signature checks. You normally - get the object back as a result of a SecureMessage operation. - */ - SecureMessageSignature(); - - /** - Create a signature check object - - User applications don't normally need to create signature checks. You normally - get the object back as a result of a SecureMessage operation. - - \param r the result of the check - \param v the Validity of the key validation check - \param key the key associated with the signature - \param ts the timestamp associated with the signature - */ - SecureMessageSignature(IdentityResult r, Validity v, const SecureMessageKey &key, const QDateTime &ts); - - /** - Standard copy constructor - - \param from the source signature object - */ - SecureMessageSignature(const SecureMessageSignature &from); - - ~SecureMessageSignature(); - - /** - Standard assignment operator - - \param from the source signature object - */ - SecureMessageSignature & operator=(const SecureMessageSignature &from); - - /** - get the results of the identity check on this signature - */ - IdentityResult identityResult() const; - - /** - get the results of the key validation check on this signature - */ - Validity keyValidity() const; - - /** - get the key associated with this signature - */ - SecureMessageKey key() const; - - /** - get the timestamp associated with this signature - */ - QDateTime timestamp() const; + /** + The result of identity verification + */ + enum IdentityResult { + Valid, ///< indentity is verified, matches signature + InvalidSignature, ///< valid key provided, but signature failed + InvalidKey, ///< invalid key provided + NoKey ///< identity unknown + }; + + /** + Create an empty signature check object. + + User applications don't normally need to create signature checks. You normally + get the object back as a result of a SecureMessage operation. + */ + SecureMessageSignature(); + + /** + Create a signature check object + + User applications don't normally need to create signature checks. You normally + get the object back as a result of a SecureMessage operation. + + \param r the result of the check + \param v the Validity of the key validation check + \param key the key associated with the signature + \param ts the timestamp associated with the signature + */ + SecureMessageSignature(IdentityResult r, Validity v, const SecureMessageKey &key, const QDateTime &ts); + + /** + Standard copy constructor + + \param from the source signature object + */ + SecureMessageSignature(const SecureMessageSignature &from); + + ~SecureMessageSignature(); + + /** + Standard assignment operator + + \param from the source signature object + */ + SecureMessageSignature &operator=(const SecureMessageSignature &from); + + /** + get the results of the identity check on this signature + */ + IdentityResult identityResult() const; + + /** + get the results of the key validation check on this signature + */ + Validity keyValidity() const; + + /** + get the key associated with this signature + */ + SecureMessageKey key() const; + + /** + get the timestamp associated with this signature + */ + QDateTime timestamp() const; private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; /** A list of signatures */ typedef QList SecureMessageSignatureList; - /** \class SecureMessage qca_securemessage.h QtCrypto @@ -296,13 +294,13 @@ if(msg.success()) { - QByteArray result = msg.read(); - // result now contains the clearsign text data + QByteArray result = msg.read(); + // result now contains the clearsign text data } else { - // error - ... + // error + ... } \endcode @@ -319,475 +317,471 @@ */ class QCA_EXPORT SecureMessage : public QObject, public Algorithm { - Q_OBJECT + Q_OBJECT public: - /** - The type of secure message - */ - enum Type - { - OpenPGP, ///< a Pretty Good Privacy message - CMS ///< a Cryptographic Message Syntax message - }; - - /** - The type of message signature - */ - enum SignMode - { - Message, ///< the message includes the signature - Clearsign, ///< the message is clear signed - Detached ///< the signature is detached - }; - - /** - Formats for secure messages - */ - enum Format - { - Binary, ///< DER/binary - Ascii ///< PEM/ascii-armored - }; - - /** - Errors for secure messages - */ - enum Error - { - ErrorPassphrase, ///< passphrase was either wrong or not provided - ErrorFormat, ///< input format was bad - ErrorSignerExpired, ///< signing key is expired - ErrorSignerInvalid, ///< signing key is invalid in some way - ErrorEncryptExpired, ///< encrypting key is expired - ErrorEncryptUntrusted, ///< encrypting key is untrusted - ErrorEncryptInvalid, ///< encrypting key is invalid in some way - ErrorNeedCard, ///< pgp card is missing - ErrorCertKeyMismatch, ///< certificate and private key don't match - ErrorUnknown, ///< other error - ErrorSignerRevoked, ///< signing key is revoked - ErrorSignatureExpired, ///< signature is expired - ErrorEncryptRevoked ///< encrypting key is revoked - }; - - /** - Create a new secure message - - This constructor uses an existing - SecureMessageSystem object (for example, an OpenPGP - or CMS object) to generate a specific kind of - secure message. - - \param system a pre-existing and configured SecureMessageSystem - object - */ - SecureMessage(SecureMessageSystem *system); - ~SecureMessage(); - - /** - The Type of secure message - */ - Type type() const; - - /** - Test if the message type supports multiple - (parallel) signatures. - - \return true if the secure message support multiple - parallel signatures - - \note PGP cannot do this - it is primarily a CMS - feature - */ - bool canSignMultiple() const; - - /** - True if the SecureMessageSystem can clearsign - messages. - - \note CMS cannot clearsign - this is normally only - available for PGP - */ - bool canClearsign() const; - - /** - True if the SecureMessageSystem can both sign and - encrypt (in the same operation). - - \note CMS cannot do an integrated sign/encrypt - - this is normally only available for PGP. You can do - separate signing and encrypting operations on the - same message with CMS though. - */ - bool canSignAndEncrypt() const; - - /** - Reset the object state to that of original construction. - Now a new operation can be performed immediately. - */ - void reset(); - - /** - Returns true if bundling of the signer certificate chain is - enabled - */ - bool bundleSignerEnabled() const; - - /** - Returns true if inclusion of S/MIME attributes is enabled - */ - bool smimeAttributesEnabled() const; - - /** - Return the format type set for this message - */ - Format format() const; - - /** - Return the recipient(s) set for this message with setRecipient() or - setRecipients() - */ - SecureMessageKeyList recipientKeys() const; - - /** - Return the signer(s) set for this message with setSigner() or - setSigners() - */ - SecureMessageKeyList signerKeys() const; - - /** - For CMS only, this will bundle the signer certificate chain - into the message. This allows a message to be verified - on its own, without the need to have obtained the signer's - certificate in advance. Email clients using S/MIME often - bundle the signer, greatly simplifying key management. - - This behavior is enabled by default. - - \param b whether to bundle (if true) or not (false) - */ - void setBundleSignerEnabled(bool b); - - /** - For CMS only, this will put extra attributes into the - message related to S/MIME, such as the preferred - type of algorithm to use in replies. The attributes - used are decided by the provider. - - This behavior is enabled by default. - - \param b whether to embed extra attribues (if true) or not (false) - */ - void setSMIMEAttributesEnabled(bool b); - - /** - Set the Format used for messages - - The default is Binary. - - \param f whether to use Binary or Ascii - */ - void setFormat(Format f); - - /** - Set the recipient for an encrypted message - - \param key the recipient's key - - \sa setRecipients - */ - void setRecipient(const SecureMessageKey &key); - - /** - Set the list of recipients for an encrypted message. - - For a list with one item, this has the same effect as setRecipient. - - \param keys the recipients' key - - \sa setRecipient - */ - void setRecipients(const SecureMessageKeyList &keys); - - /** - Set the signer for a signed message. - - This is used for both creating signed messages as well as for - verifying CMS messages that have no signer bundled. - - \param key the key associated with the signer - - \sa setSigners - */ - void setSigner(const SecureMessageKey &key); - - /** - Set the list of signers for a signed message. - - This is used for both creating signed messages as well as for - verifying CMS messages that have no signer bundled. - - For a list with one item, this has the same effect as setSigner. - - \param keys the key associated with the signer - - \sa setSigner - */ - void setSigners(const SecureMessageKeyList &keys); - - /** - Start an encryption operation - - You will normally use this with some code along - these lines: - \code -encryptingObj.startEncrypt(); -encryptingObj.update(message); -// perhaps some more update()s -encryptingObj.end(); - \endcode - - Each update() may (or may not) result in some - encrypted data, as indicated by the readyRead() - signal being emitted. Alternatively, you can wait - until the whole message is available (using either - waitForFinished(), or use the finished() - signal. The encrypted message can then be read - using the read() method. - */ - void startEncrypt(); - - /** - Start an decryption operation - - You will normally use this with some code along - these lines: - \code -decryptingObj.startEncrypt(); -decryptingObj.update(message); -// perhaps some more update()s -decryptingObj.end(); - \endcode - - Each update() may (or may not) result in some - decrypted data, as indicated by the readyRead() - signal being emitted. Alternatively, you can wait - until the whole message is available (using either - waitForFinished(), or the finished() - signal). The decrypted message can then be read - using the read() method. - - \note If decrypted result is also signed (not for - CMS), then the signature will be verified during - this operation. - */ - void startDecrypt(); - - /** - Start a signing operation - - You will normally use this with some code along - these lines: - \code -signingObj.startSign(QCA::SecureMessage::Detached) -signingObj.update(message); -// perhaps some more update()s -signingObj.end(); - \endcode - - For Detached signatures, you won't get any results - until the whole process is done - you either - waitForFinished(), or use the finished() signal, to - figure out when you can get the signature (using - the signature() method, not using read()). For - other formats, you can use the readyRead() signal - to determine when there may be part of a signed - message to read(). - - \param m the mode that will be used to generate the - signature - */ - void startSign(SignMode m = Message); - - /** - Start a verification operation - - \param detachedSig the detached signature to - verify. Do not pass a signature for other signature - types. - */ - void startVerify(const QByteArray &detachedSig = QByteArray()); - - /** - Start a combined signing and encrypting - operation. You use this in the same way as - startEncrypt(). - - \note This may not be possible (e.g. CMS - cannot do this) - see canSignAndEncrypt() for a - suitable test. - */ - void startSignAndEncrypt(); - - /** - Process a message (or the next part of a message) - in the current operation. You need to have already - set up the message (startEncrypt(), startDecrypt(), - startSign(), startSignAndEncrypt() and - startVerify()) before calling this method. - - \param in the data to process - */ - void update(const QByteArray &in); - - /** - Read the available data. - - \note For detached signatures, you don't get - anything back using this method. Use signature() to - get the detached signature(). - */ - QByteArray read(); - - /** - The number of bytes available to be read. - */ - int bytesAvailable() const; - - /** - Complete an operation. - - You need to call this method after you have - processed the message (which you pass in as the - argument to update(). - - \note the results of the operation are not - available as soon as this method returns. You need - to wait for the finished() signal, or use - waitForFinished(). - */ - void end(); - - /** - Block until the operation (encryption, decryption, - signing or verifying) completes. - - \param msecs the number of milliseconds to wait for - the operation to complete. Pass -1 to wait - indefinitely. - - \note You should not use this in GUI - applications where the blocking behaviour looks - like a hung application. Instead, connect the - finished() signal to a slot that handles the - results. - - \note This synchronous operation may require event handling, and so - it must not be called from the same thread as an EventHandler. - */ - bool waitForFinished(int msecs = 30000); - - /** - Indicates whether or not the operation was successful - or failed. If this function returns false, then - the reason for failure can be obtained with errorCode(). - - \sa errorCode - \sa diagnosticText - */ - bool success() const; - - /** - Returns the failure code. - - \sa success - \sa diagnosticText - */ - Error errorCode() const; - - /** - The signature for the message. This is only used - for Detached signatures. For other message types, - you get the message and signature together using - read(). - */ - QByteArray signature() const; - - /** - The name of the hash used for the signature process - */ - QString hashName() const; - - /** - Test if the message was signed. - - This is true for OpenPGP if the decrypted message - was also signed. - - \return true if the message was signed. - */ - bool wasSigned() const; - - /** - Verify that the message signature is correct. - - \return true if the signature is valid for the - message, otherwise return false - */ - bool verifySuccess() const; - - /** - Information on the signer for the message - */ - SecureMessageSignature signer() const; - - /** - Information on the signers for the message. - - This is only meaningful if the message type supports - multiple signatures (see canSignMultiple() for a - suitable test). - */ - SecureMessageSignatureList signers() const; - - /** - Returns a log of technical information about the operation, - which may be useful for presenting to the user in an - advanced error dialog. - */ - QString diagnosticText() const; + /** + The type of secure message + */ + enum Type { + OpenPGP, ///< a Pretty Good Privacy message + CMS ///< a Cryptographic Message Syntax message + }; + + /** + The type of message signature + */ + enum SignMode { + Message, ///< the message includes the signature + Clearsign, ///< the message is clear signed + Detached ///< the signature is detached + }; + + /** + Formats for secure messages + */ + enum Format { + Binary, ///< DER/binary + Ascii ///< PEM/ascii-armored + }; + + /** + Errors for secure messages + */ + enum Error { + ErrorPassphrase, ///< passphrase was either wrong or not provided + ErrorFormat, ///< input format was bad + ErrorSignerExpired, ///< signing key is expired + ErrorSignerInvalid, ///< signing key is invalid in some way + ErrorEncryptExpired, ///< encrypting key is expired + ErrorEncryptUntrusted, ///< encrypting key is untrusted + ErrorEncryptInvalid, ///< encrypting key is invalid in some way + ErrorNeedCard, ///< pgp card is missing + ErrorCertKeyMismatch, ///< certificate and private key don't match + ErrorUnknown, ///< other error + ErrorSignerRevoked, ///< signing key is revoked + ErrorSignatureExpired, ///< signature is expired + ErrorEncryptRevoked ///< encrypting key is revoked + }; + + /** + Create a new secure message + + This constructor uses an existing + SecureMessageSystem object (for example, an OpenPGP + or CMS object) to generate a specific kind of + secure message. + + \param system a pre-existing and configured SecureMessageSystem + object + */ + SecureMessage(SecureMessageSystem *system); + ~SecureMessage(); + + /** + The Type of secure message + */ + Type type() const; + + /** + Test if the message type supports multiple + (parallel) signatures. + + \return true if the secure message support multiple + parallel signatures + + \note PGP cannot do this - it is primarily a CMS + feature + */ + bool canSignMultiple() const; + + /** + True if the SecureMessageSystem can clearsign + messages. + + \note CMS cannot clearsign - this is normally only + available for PGP + */ + bool canClearsign() const; + + /** + True if the SecureMessageSystem can both sign and + encrypt (in the same operation). + + \note CMS cannot do an integrated sign/encrypt - + this is normally only available for PGP. You can do + separate signing and encrypting operations on the + same message with CMS though. + */ + bool canSignAndEncrypt() const; + + /** + Reset the object state to that of original construction. + Now a new operation can be performed immediately. + */ + void reset(); + + /** + Returns true if bundling of the signer certificate chain is + enabled + */ + bool bundleSignerEnabled() const; + + /** + Returns true if inclusion of S/MIME attributes is enabled + */ + bool smimeAttributesEnabled() const; + + /** + Return the format type set for this message + */ + Format format() const; + + /** + Return the recipient(s) set for this message with setRecipient() or + setRecipients() + */ + SecureMessageKeyList recipientKeys() const; + + /** + Return the signer(s) set for this message with setSigner() or + setSigners() + */ + SecureMessageKeyList signerKeys() const; + + /** + For CMS only, this will bundle the signer certificate chain + into the message. This allows a message to be verified + on its own, without the need to have obtained the signer's + certificate in advance. Email clients using S/MIME often + bundle the signer, greatly simplifying key management. + + This behavior is enabled by default. + + \param b whether to bundle (if true) or not (false) + */ + void setBundleSignerEnabled(bool b); + + /** + For CMS only, this will put extra attributes into the + message related to S/MIME, such as the preferred + type of algorithm to use in replies. The attributes + used are decided by the provider. + + This behavior is enabled by default. + + \param b whether to embed extra attribues (if true) or not (false) + */ + void setSMIMEAttributesEnabled(bool b); + + /** + Set the Format used for messages + + The default is Binary. + + \param f whether to use Binary or Ascii + */ + void setFormat(Format f); + + /** + Set the recipient for an encrypted message + + \param key the recipient's key + + \sa setRecipients + */ + void setRecipient(const SecureMessageKey &key); + + /** + Set the list of recipients for an encrypted message. + + For a list with one item, this has the same effect as setRecipient. + + \param keys the recipients' key + + \sa setRecipient + */ + void setRecipients(const SecureMessageKeyList &keys); + + /** + Set the signer for a signed message. + + This is used for both creating signed messages as well as for + verifying CMS messages that have no signer bundled. + + \param key the key associated with the signer + + \sa setSigners + */ + void setSigner(const SecureMessageKey &key); + + /** + Set the list of signers for a signed message. + + This is used for both creating signed messages as well as for + verifying CMS messages that have no signer bundled. + + For a list with one item, this has the same effect as setSigner. + + \param keys the key associated with the signer + + \sa setSigner + */ + void setSigners(const SecureMessageKeyList &keys); + + /** + Start an encryption operation + + You will normally use this with some code along + these lines: + \code + encryptingObj.startEncrypt(); + encryptingObj.update(message); + // perhaps some more update()s + encryptingObj.end(); + \endcode + + Each update() may (or may not) result in some + encrypted data, as indicated by the readyRead() + signal being emitted. Alternatively, you can wait + until the whole message is available (using either + waitForFinished(), or use the finished() + signal. The encrypted message can then be read + using the read() method. + */ + void startEncrypt(); + + /** + Start an decryption operation + + You will normally use this with some code along + these lines: + \code + decryptingObj.startEncrypt(); + decryptingObj.update(message); + // perhaps some more update()s + decryptingObj.end(); + \endcode + + Each update() may (or may not) result in some + decrypted data, as indicated by the readyRead() + signal being emitted. Alternatively, you can wait + until the whole message is available (using either + waitForFinished(), or the finished() + signal). The decrypted message can then be read + using the read() method. + + \note If decrypted result is also signed (not for + CMS), then the signature will be verified during + this operation. + */ + void startDecrypt(); + + /** + Start a signing operation + + You will normally use this with some code along + these lines: + \code + signingObj.startSign(QCA::SecureMessage::Detached) + signingObj.update(message); + // perhaps some more update()s + signingObj.end(); + \endcode + + For Detached signatures, you won't get any results + until the whole process is done - you either + waitForFinished(), or use the finished() signal, to + figure out when you can get the signature (using + the signature() method, not using read()). For + other formats, you can use the readyRead() signal + to determine when there may be part of a signed + message to read(). + + \param m the mode that will be used to generate the + signature + */ + void startSign(SignMode m = Message); + + /** + Start a verification operation + + \param detachedSig the detached signature to + verify. Do not pass a signature for other signature + types. + */ + void startVerify(const QByteArray &detachedSig = QByteArray()); + + /** + Start a combined signing and encrypting + operation. You use this in the same way as + startEncrypt(). + + \note This may not be possible (e.g. CMS + cannot do this) - see canSignAndEncrypt() for a + suitable test. + */ + void startSignAndEncrypt(); + + /** + Process a message (or the next part of a message) + in the current operation. You need to have already + set up the message (startEncrypt(), startDecrypt(), + startSign(), startSignAndEncrypt() and + startVerify()) before calling this method. + + \param in the data to process + */ + void update(const QByteArray &in); + + /** + Read the available data. + + \note For detached signatures, you don't get + anything back using this method. Use signature() to + get the detached signature(). + */ + QByteArray read(); + + /** + The number of bytes available to be read. + */ + int bytesAvailable() const; + + /** + Complete an operation. + + You need to call this method after you have + processed the message (which you pass in as the + argument to update(). + + \note the results of the operation are not + available as soon as this method returns. You need + to wait for the finished() signal, or use + waitForFinished(). + */ + void end(); + + /** + Block until the operation (encryption, decryption, + signing or verifying) completes. + + \param msecs the number of milliseconds to wait for + the operation to complete. Pass -1 to wait + indefinitely. + + \note You should not use this in GUI + applications where the blocking behaviour looks + like a hung application. Instead, connect the + finished() signal to a slot that handles the + results. + + \note This synchronous operation may require event handling, and so + it must not be called from the same thread as an EventHandler. + */ + bool waitForFinished(int msecs = 30000); + + /** + Indicates whether or not the operation was successful + or failed. If this function returns false, then + the reason for failure can be obtained with errorCode(). + + \sa errorCode + \sa diagnosticText + */ + bool success() const; + + /** + Returns the failure code. + + \sa success + \sa diagnosticText + */ + Error errorCode() const; + + /** + The signature for the message. This is only used + for Detached signatures. For other message types, + you get the message and signature together using + read(). + */ + QByteArray signature() const; + + /** + The name of the hash used for the signature process + */ + QString hashName() const; + + /** + Test if the message was signed. + + This is true for OpenPGP if the decrypted message + was also signed. + + \return true if the message was signed. + */ + bool wasSigned() const; + + /** + Verify that the message signature is correct. + + \return true if the signature is valid for the + message, otherwise return false + */ + bool verifySuccess() const; + + /** + Information on the signer for the message + */ + SecureMessageSignature signer() const; + + /** + Information on the signers for the message. + + This is only meaningful if the message type supports + multiple signatures (see canSignMultiple() for a + suitable test). + */ + SecureMessageSignatureList signers() const; + + /** + Returns a log of technical information about the operation, + which may be useful for presenting to the user in an + advanced error dialog. + */ + QString diagnosticText() const; Q_SIGNALS: - /** - This signal is emitted when there is some data to - read. Typically you connect this signal to a slot - that does a read() of the available data. - - \note This signal does not mean that the processing - of a message is necessarily complete - see - finished(). - */ - void readyRead(); - - /** - This signal is emitted when data has been accepted - by the message processor. - - \param bytes the number of bytes written - */ - void bytesWritten(int bytes); - - /** - This signal is emitted when the message is fully - processed. - */ - void finished(); + /** + This signal is emitted when there is some data to + read. Typically you connect this signal to a slot + that does a read() of the available data. + + \note This signal does not mean that the processing + of a message is necessarily complete - see + finished(). + */ + void readyRead(); + + /** + This signal is emitted when data has been accepted + by the message processor. + + \param bytes the number of bytes written + */ + void bytesWritten(int bytes); + + /** + This signal is emitted when the message is fully + processed. + */ + void finished(); private: - Q_DISABLE_COPY(SecureMessage) + Q_DISABLE_COPY(SecureMessage) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -802,28 +796,28 @@ */ class QCA_EXPORT SecureMessageSystem : public QObject, public Algorithm { - Q_OBJECT + Q_OBJECT public: - ~SecureMessageSystem(); + ~SecureMessageSystem(); protected: - /** - Protected constructor for SecureMessageSystem - classes. You are meant to be using a subclass (such - as OpenPGP or CMS) - you only need to worry about - this class if you are creating a whole new - SecureMessageSystem type. - - \param parent the parent object for this object - \param type the name of the Type of - SecureMessageSystem to create - \param provider the provider to use, if a specific - provider is required. - */ - SecureMessageSystem(QObject *parent, const QString &type, const QString &provider); + /** + Protected constructor for SecureMessageSystem + classes. You are meant to be using a subclass (such + as OpenPGP or CMS) - you only need to worry about + this class if you are creating a whole new + SecureMessageSystem type. + + \param parent the parent object for this object + \param type the name of the Type of + SecureMessageSystem to create + \param provider the provider to use, if a specific + provider is required. + */ + SecureMessageSystem(QObject *parent, const QString &type, const QString &provider); private: - Q_DISABLE_COPY(SecureMessageSystem) + Q_DISABLE_COPY(SecureMessageSystem) }; /** @@ -839,23 +833,23 @@ */ class QCA_EXPORT OpenPGP : public SecureMessageSystem { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param parent the parent object for this object - \param provider the provider to use, if a specific - provider is required - */ - explicit OpenPGP(QObject *parent = 0, const QString &provider = QString()); - ~OpenPGP(); + \param parent the parent object for this object + \param provider the provider to use, if a specific + provider is required + */ + explicit OpenPGP(QObject *parent = 0, const QString &provider = QString()); + ~OpenPGP(); private: - Q_DISABLE_COPY(OpenPGP) + Q_DISABLE_COPY(OpenPGP) - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -885,72 +879,72 @@ */ class QCA_EXPORT CMS : public SecureMessageSystem { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param parent the parent object for this object - \param provider the provider to use, if a specific - provider is required - */ - explicit CMS(QObject *parent = 0, const QString &provider = QString()); - ~CMS(); - - /** - Return the trusted certificates set for this object - */ - CertificateCollection trustedCertificates() const; - - /** - Return the untrusted certificates set for this object - */ - CertificateCollection untrustedCertificates() const; - - /** - Return the private keys set for this object - */ - SecureMessageKeyList privateKeys() const; - - /** - Set the trusted certificates to use for the - messages built using this CMS object. - - \param trusted the collection of trusted - certificates to use - */ - void setTrustedCertificates(const CertificateCollection &trusted); - - /** - Set the untrusted certificates to use for the - messages built using this CMS object. - - This function is useful when verifying messages that don't - contain the certificates (or intermediate signers) within - the CMS blob. In order to verify such messages, you'll - have to pass the possible signer certs with this function. - - \param untrusted the collection of untrusted - certificates to use - */ - void setUntrustedCertificates(const CertificateCollection &untrusted); - - /** - Set the private keys to use for the messages built - using this CMS object. - - Keys are required for decrypting and signing (not - for encrypting or verifying). - - \param keys the collection of keys to use - */ - void setPrivateKeys(const SecureMessageKeyList &keys); + /** + Standard constructor + + \param parent the parent object for this object + \param provider the provider to use, if a specific + provider is required + */ + explicit CMS(QObject *parent = 0, const QString &provider = QString()); + ~CMS(); + + /** + Return the trusted certificates set for this object + */ + CertificateCollection trustedCertificates() const; + + /** + Return the untrusted certificates set for this object + */ + CertificateCollection untrustedCertificates() const; + + /** + Return the private keys set for this object + */ + SecureMessageKeyList privateKeys() const; + + /** + Set the trusted certificates to use for the + messages built using this CMS object. + + \param trusted the collection of trusted + certificates to use + */ + void setTrustedCertificates(const CertificateCollection &trusted); + + /** + Set the untrusted certificates to use for the + messages built using this CMS object. + + This function is useful when verifying messages that don't + contain the certificates (or intermediate signers) within + the CMS blob. In order to verify such messages, you'll + have to pass the possible signer certs with this function. + + \param untrusted the collection of untrusted + certificates to use + */ + void setUntrustedCertificates(const CertificateCollection &untrusted); + + /** + Set the private keys to use for the messages built + using this CMS object. + + Keys are required for decrypting and signing (not + for encrypting or verifying). + + \param keys the collection of keys to use + */ + void setPrivateKeys(const SecureMessageKeyList &keys); private: - Q_DISABLE_COPY(CMS) + Q_DISABLE_COPY(CMS) - class Private; - Private *d; + class Private; + Private *d; }; } diff --git a/include/QtCrypto/qca_support.h b/include/QtCrypto/qca_support.h --- a/include/QtCrypto/qca_support.h +++ b/include/QtCrypto/qca_support.h @@ -48,7 +48,8 @@ #include "qca_export.h" #include "qca_tools.h" -namespace QCA { +namespace QCA +{ /** Convenience method to determine the return type of a method @@ -88,7 +89,7 @@ \param obj the QMetaObject for the object \param method the name of the method (without the arguments or brackets) - \param argTypes the list of argument types of the method + \param argTypes the list of argument types of the method \return the name of the type that this method will return with the specified argument types. @@ -170,35 +171,35 @@ \code class Counter : public QObject { - Q_OBJECT + Q_OBJECT private: - int x; - QTimer timer; + int x; + QTimer timer; public: - Counter() : timer(this) - { - x = 0; - connect(&timer, SIGNAL(timeout()), SLOT(t_timeout())); - } + Counter() : timer(this) + { + x = 0; + connect(&timer, SIGNAL(timeout()), SLOT(t_timeout())); + } public slots: - void start(int seconds) - { - timer.setInterval(seconds * 1000); - timer.start(); - } + void start(int seconds) + { + timer.setInterval(seconds * 1000); + timer.start(); + } - int value() const - { - return x; - } + int value() const + { + return x; + } private slots: - void t_timeout() - { - ++x; - } + void t_timeout() + { + ++x; + } }; \endcode @@ -210,34 +211,34 @@ \code class CounterThread : public SyncThread { - Q_OBJECT + Q_OBJECT public: - Counter *counter; - - CounterThread(QObject *parent) : SyncThread(parent) - { - counter = 0; - } - - ~CounterThread() - { - // SyncThread will stop the thread on destruct, but since our - // atStop() function makes references to CounterThread's - // members, we need to shutdown here, before CounterThread - // destructs. - stop(); - } + Counter *counter; + + CounterThread(QObject *parent) : SyncThread(parent) + { + counter = 0; + } + + ~CounterThread() + { + // SyncThread will stop the thread on destruct, but since our + // atStop() function makes references to CounterThread's + // members, we need to shutdown here, before CounterThread + // destructs. + stop(); + } protected: - virtual void atStart() - { - counter = new Counter; - } - - virtual void atStop() - { - delete counter; - } + virtual void atStart() + { + counter = new Counter; + } + + virtual void atStop() + { + delete counter; + } }; \endcode @@ -271,78 +272,78 @@ */ class QCA_EXPORT SyncThread : public QThread { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param parent the parent object for this parent. - */ - SyncThread(QObject *parent = 0); - - /** - Calls stop() and then destructs - - \note Subclasses should call stop() in their own destructor - */ - ~SyncThread(); - - /** - Starts the thread, begins the event loop the thread, and then - calls atStart() in the thread. This function will block until - atStart() has returned. - */ - void start(); - - /** - Stops the event loop of the thread, calls atStop() in the thread, - and instructs the thread to finish. This function will block - until the thread has finished. - */ - void stop(); - - /** - Calls a slot of an object in the thread. This function will block - until the slot has returned. - - It is possible for the call to fail, for example if the method - does not exist. - - The arguments and return value of the call use QVariant. If the - method has no return value (returns void), then the returned - QVariant will be null. - - \param obj the object to call the method on - \param method the name of the method (without the arguments or - brackets) - \param args the list of arguments to use in the method call - \param ok if not 0, true is stored here if the call succeeds, - otherwise false is stored here. - */ - QVariant call(QObject *obj, const QByteArray &method, const QVariantList &args = QVariantList(), bool *ok = 0); + /** + Standard constructor + + \param parent the parent object for this parent. + */ + SyncThread(QObject *parent = 0); + + /** + Calls stop() and then destructs + + \note Subclasses should call stop() in their own destructor + */ + ~SyncThread(); + + /** + Starts the thread, begins the event loop the thread, and then + calls atStart() in the thread. This function will block until + atStart() has returned. + */ + void start(); + + /** + Stops the event loop of the thread, calls atStop() in the thread, + and instructs the thread to finish. This function will block + until the thread has finished. + */ + void stop(); + + /** + Calls a slot of an object in the thread. This function will block + until the slot has returned. + + It is possible for the call to fail, for example if the method + does not exist. + + The arguments and return value of the call use QVariant. If the + method has no return value (returns void), then the returned + QVariant will be null. + + \param obj the object to call the method on + \param method the name of the method (without the arguments or + brackets) + \param args the list of arguments to use in the method call + \param ok if not 0, true is stored here if the call succeeds, + otherwise false is stored here. + */ + QVariant call(QObject *obj, const QByteArray &method, const QVariantList &args = QVariantList(), bool *ok = 0); protected: - /** - Reimplement this to perform your initialization - */ - virtual void atStart() = 0; + /** + Reimplement this to perform your initialization + */ + virtual void atStart() = 0; - /** - Reimplement this to perform your deinitialization - */ - virtual void atEnd() = 0; + /** + Reimplement this to perform your deinitialization + */ + virtual void atEnd() = 0; - /** - Starts the event loop and calls atStart and atStop as necessary - */ - virtual void run(); + /** + Starts the event loop and calls atStart and atStop as necessary + */ + virtual void run(); private: - Q_DISABLE_COPY(SyncThread) + Q_DISABLE_COPY(SyncThread) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -352,35 +353,35 @@ */ class QCA_EXPORT Synchronizer : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param parent the parent object to this object - */ - Synchronizer(QObject *parent); - ~Synchronizer(); + \param parent the parent object to this object + */ + Synchronizer(QObject *parent); + ~Synchronizer(); - /** - Call to pause execution in this thread. This function - will block until conditionMet() is called. + /** + Call to pause execution in this thread. This function + will block until conditionMet() is called. - \param msecs the time to wait before proceeding. The default - timeout value (-1) indicates to wait indefinitely. - */ - bool waitForCondition(int msecs = -1); + \param msecs the time to wait before proceeding. The default + timeout value (-1) indicates to wait indefinitely. + */ + bool waitForCondition(int msecs = -1); - /** - Call to continue execution in the paused thread. - */ - void conditionMet(); + /** + Call to continue execution in the paused thread. + */ + void conditionMet(); private: - Q_DISABLE_COPY(Synchronizer) + Q_DISABLE_COPY(Synchronizer) - class Private; - Private *d; + class Private; + Private *d; }; /** @@ -392,53 +393,53 @@ the directory changes, the changed() signal is emitted. \note QFileSystemWatcher has very similar functionality - to this class. You should evaluate this class and + to this class. You should evaluate this class and QFileSystemWatcher to determine which better suits your application needs. \ingroup UserAPI */ class QCA_EXPORT DirWatch : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param dir the name of the directory to watch. If not - set in the constructor, you can set it using setDirName() - \param parent the parent object for this object - */ - explicit DirWatch(const QString &dir = QString(), QObject *parent = 0); - ~DirWatch(); + \param dir the name of the directory to watch. If not + set in the constructor, you can set it using setDirName() + \param parent the parent object for this object + */ + explicit DirWatch(const QString &dir = QString(), QObject *parent = 0); + ~DirWatch(); - /** - The name of the directory that is being monitored - */ - QString dirName() const; + /** + The name of the directory that is being monitored + */ + QString dirName() const; - /** - Change the directory being monitored + /** + Change the directory being monitored - \param dir the name of the directory to monitor - */ - void setDirName(const QString &dir); + \param dir the name of the directory to monitor + */ + void setDirName(const QString &dir); Q_SIGNALS: - /** - The changed signal is emitted when the directory is - changed (e.g. modified by addition or deletion of a - file within the directory, or the deletion of the - directory) - */ - void changed(); + /** + The changed signal is emitted when the directory is + changed (e.g. modified by addition or deletion of a + file within the directory, or the deletion of the + directory) + */ + void changed(); private: - Q_DISABLE_COPY(DirWatch) + Q_DISABLE_COPY(DirWatch) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -450,51 +451,51 @@ the file changes, the changed() signal is emitted. \note QFileSystemWatcher has very similar functionality - to this class. You should evaluate this class and + to this class. You should evaluate this class and QFileSystemWatcher to determine which better suits your application needs. \ingroup UserAPI */ class QCA_EXPORT FileWatch : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param file the name of the file to watch. If not - in this object, you can set it using setFileName() - \param parent the parent object for this object - */ - explicit FileWatch(const QString &file = QString(), QObject *parent = 0); - ~FileWatch(); + \param file the name of the file to watch. If not + in this object, you can set it using setFileName() + \param parent the parent object for this object + */ + explicit FileWatch(const QString &file = QString(), QObject *parent = 0); + ~FileWatch(); - /** - The name of the file that is being monitored - */ - QString fileName() const; + /** + The name of the file that is being monitored + */ + QString fileName() const; - /** - Change the file being monitored + /** + Change the file being monitored - \param file the name of the file to monitor - */ - void setFileName(const QString &file); + \param file the name of the file to monitor + */ + void setFileName(const QString &file); Q_SIGNALS: - /** - The changed signal is emitted when the file is - changed (e.g. modified, deleted) - */ - void changed(); + /** + The changed signal is emitted when the file is + changed (e.g. modified, deleted) + */ + void changed(); private: - Q_DISABLE_COPY(FileWatch) + Q_DISABLE_COPY(FileWatch) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; class ConsolePrivate; @@ -551,125 +552,122 @@ */ class QCA_EXPORT Console : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - The type of console object - */ - enum Type - { - Tty, ///< physical console - Stdio ///< stdin/stdout - }; - /** - The type of I/O to use with the console object. - */ - enum ChannelMode - { - Read, ///< Read only (equivalent to stdin) - ReadWrite ///< Read/write (equivalent to stdin and stdout) - }; - - /** - The nature of the console operation - */ - enum TerminalMode - { - Default, ///< use default terminal settings - Interactive ///< char-by-char input, no echo - }; - - /** - Standard constructor - - Note that library code should not create a new Console object - without checking whether there is already a Console object of - the required Type. See the main documentation for Console for the - rationale for this. - - \param type the Type of Console object to create - \param cmode the ChannelMode (I/O type) to use - \param tmode the TerminalMode to use - \param parent the parent object for this object - - \sa ttyInstance() and stdioInstance for static methods that allow - you to test whether there is already a Console object of the - required Type, and if there is, obtain a reference to that object. - */ - Console(Type type, ChannelMode cmode, TerminalMode tmode, QObject *parent = 0); - ~Console(); - - /** - The Type of this Console object - */ - Type type() const; - - /** - The ChannelMode of this Console object - */ - ChannelMode channelMode() const; - - /** - The TerminalMode of this Console object - */ - TerminalMode terminalMode() const; - - /** - Test whether standard input is redirected. - - \sa type() and channelMode() - */ - static bool isStdinRedirected(); - - /** - Test whether standard output is redirected. - - \sa type() and channelMode() - */ - static bool isStdoutRedirected(); - - /** - The current terminal-type console object - - \return null if there is no current Console - of this type, otherwise the Console to use - */ - static Console *ttyInstance(); - - /** - The current stdio-type console object - - \return null if there is no current Console - of this type, otherwise the Console to use - */ - static Console *stdioInstance(); - - /** - Release the Console - - This allows access to buffers containing any remaining data - */ - void release(); - - /** - Obtain remaining data from the Console, awaiting - a read operation - */ - QByteArray bytesLeftToRead(); - - /** - Obtain remaining data from the Console, awaiting - a write operation - */ - QByteArray bytesLeftToWrite(); + /** + The type of console object + */ + enum Type { + Tty, ///< physical console + Stdio ///< stdin/stdout + }; + /** + The type of I/O to use with the console object. + */ + enum ChannelMode { + Read, ///< Read only (equivalent to stdin) + ReadWrite ///< Read/write (equivalent to stdin and stdout) + }; + + /** + The nature of the console operation + */ + enum TerminalMode { + Default, ///< use default terminal settings + Interactive ///< char-by-char input, no echo + }; + + /** + Standard constructor + + Note that library code should not create a new Console object + without checking whether there is already a Console object of + the required Type. See the main documentation for Console for the + rationale for this. + + \param type the Type of Console object to create + \param cmode the ChannelMode (I/O type) to use + \param tmode the TerminalMode to use + \param parent the parent object for this object + + \sa ttyInstance() and stdioInstance for static methods that allow + you to test whether there is already a Console object of the + required Type, and if there is, obtain a reference to that object. + */ + Console(Type type, ChannelMode cmode, TerminalMode tmode, QObject *parent = 0); + ~Console(); + + /** + The Type of this Console object + */ + Type type() const; + + /** + The ChannelMode of this Console object + */ + ChannelMode channelMode() const; + + /** + The TerminalMode of this Console object + */ + TerminalMode terminalMode() const; + + /** + Test whether standard input is redirected. + + \sa type() and channelMode() + */ + static bool isStdinRedirected(); + + /** + Test whether standard output is redirected. + + \sa type() and channelMode() + */ + static bool isStdoutRedirected(); + + /** + The current terminal-type console object + + \return null if there is no current Console + of this type, otherwise the Console to use + */ + static Console *ttyInstance(); + + /** + The current stdio-type console object + + \return null if there is no current Console + of this type, otherwise the Console to use + */ + static Console *stdioInstance(); + + /** + Release the Console + + This allows access to buffers containing any remaining data + */ + void release(); + + /** + Obtain remaining data from the Console, awaiting + a read operation + */ + QByteArray bytesLeftToRead(); + + /** + Obtain remaining data from the Console, awaiting + a write operation + */ + QByteArray bytesLeftToWrite(); private: - Q_DISABLE_COPY(Console) + Q_DISABLE_COPY(Console) - friend class ConsolePrivate; - ConsolePrivate *d; + friend class ConsolePrivate; + ConsolePrivate *d; - friend class ConsoleReference; + friend class ConsoleReference; }; /** @@ -683,153 +681,152 @@ */ class QCA_EXPORT ConsoleReference : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - The security setting to use for the Console being managed. - */ - enum SecurityMode - { - SecurityDisabled, - SecurityEnabled - }; + /** + The security setting to use for the Console being managed. + */ + enum SecurityMode { + SecurityDisabled, + SecurityEnabled + }; - /** - Standard constructor + /** + Standard constructor - \param parent the parent object for this object - */ - ConsoleReference(QObject *parent = 0); - ~ConsoleReference(); + \param parent the parent object for this object + */ + ConsoleReference(QObject *parent = 0); + ~ConsoleReference(); - /** - Set the Console object to be managed, and start processing. + /** + Set the Console object to be managed, and start processing. - You typically want to use Console::ttyInstance() or - Console::stdioInstance() to obtain the required Console - reference. + You typically want to use Console::ttyInstance() or + Console::stdioInstance() to obtain the required Console + reference. - \param console reference to the Console to be managed - \param mode the SecurityMode to use for this Console. + \param console reference to the Console to be managed + \param mode the SecurityMode to use for this Console. - \sa QCA::Console for more information on how to handle the - console aspects of your application or library code. - */ - bool start(Console *console, SecurityMode mode = SecurityDisabled); + \sa QCA::Console for more information on how to handle the + console aspects of your application or library code. + */ + bool start(Console *console, SecurityMode mode = SecurityDisabled); - /** - Stop processing, and release the Console - */ - void stop(); + /** + Stop processing, and release the Console + */ + void stop(); - /** - The Console object managed by this object + /** + The Console object managed by this object - \sa start() to set the Console to be managed - */ - Console *console() const; + \sa start() to set the Console to be managed + */ + Console *console() const; - /** - The security mode setting for the Console object - managed by this object. + /** + The security mode setting for the Console object + managed by this object. - \sa start() to set the SecurityMode - */ - SecurityMode securityMode() const; + \sa start() to set the SecurityMode + */ + SecurityMode securityMode() const; - /** - Read data from the Console. + /** + Read data from the Console. - \param bytes the number of bytes to read. The default - is to read all available bytes + \param bytes the number of bytes to read. The default + is to read all available bytes - \sa readSecure() for a method suitable for reading - sensitive data. - */ - QByteArray read(int bytes = -1); + \sa readSecure() for a method suitable for reading + sensitive data. + */ + QByteArray read(int bytes = -1); - /** - Write data to the Console. + /** + Write data to the Console. - \param a the array of data to write to the Console + \param a the array of data to write to the Console - \sa writeSecure() for a method suitable for writing - sensitive data. - */ - void write(const QByteArray &a); + \sa writeSecure() for a method suitable for writing + sensitive data. + */ + void write(const QByteArray &a); - /** - Read secure data from the Console + /** + Read secure data from the Console - \param bytes the number of bytes to read. The default - is to read all available bytes + \param bytes the number of bytes to read. The default + is to read all available bytes - \sa read() which is suitable for non-sensitive data - */ - SecureArray readSecure(int bytes = -1); + \sa read() which is suitable for non-sensitive data + */ + SecureArray readSecure(int bytes = -1); - /** - Write secure data to the Console + /** + Write secure data to the Console - \param a the array of data to write to the Console + \param a the array of data to write to the Console - \sa write() which is suitable for non-sensitive data - */ - void writeSecure(const SecureArray &a); + \sa write() which is suitable for non-sensitive data + */ + void writeSecure(const SecureArray &a); - /** - Close the write channel + /** + Close the write channel - You only need to call this if writing is enabled - on the Console being managed. - */ - void closeOutput(); + You only need to call this if writing is enabled + on the Console being managed. + */ + void closeOutput(); - /** - The number of bytes available to read from the - Console being managed. - */ - int bytesAvailable() const; + /** + The number of bytes available to read from the + Console being managed. + */ + int bytesAvailable() const; - /** - The number of bytes remaining to be written - to the Console being managed - */ - int bytesToWrite() const; + /** + The number of bytes remaining to be written + to the Console being managed + */ + int bytesToWrite() const; Q_SIGNALS: - /** - Emitted when there are bytes available to read from - the Console being managed - */ - void readyRead(); + /** + Emitted when there are bytes available to read from + the Console being managed + */ + void readyRead(); - /** - Emitted when bytes are written to the Console + /** + Emitted when bytes are written to the Console - \param bytes the number of bytes that were written + \param bytes the number of bytes that were written - \sa bytesAvailable() - */ - void bytesWritten(int bytes); + \sa bytesAvailable() + */ + void bytesWritten(int bytes); - /** - Emitted when the console input is closed - */ - void inputClosed(); + /** + Emitted when the console input is closed + */ + void inputClosed(); - /** - Emitted when the console output is closed - */ - void outputClosed(); + /** + Emitted when the console output is closed + */ + void outputClosed(); private: - Q_DISABLE_COPY(ConsoleReference) + Q_DISABLE_COPY(ConsoleReference) - friend class ConsoleReferencePrivate; - ConsoleReferencePrivate *d; + friend class ConsoleReferencePrivate; + ConsoleReferencePrivate *d; - friend class Console; + friend class Console; }; /** @@ -854,78 +851,78 @@ */ class QCA_EXPORT ConsolePrompt : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param parent the parent object for this object - */ - ConsolePrompt(QObject *parent = 0); - ~ConsolePrompt(); + \param parent the parent object for this object + */ + ConsolePrompt(QObject *parent = 0); + ~ConsolePrompt(); - /** - Allow the user to enter data without it being echo'd to - the terminal. This is particularly useful for entry - of passwords, passphrases and PINs. + /** + Allow the user to enter data without it being echo'd to + the terminal. This is particularly useful for entry + of passwords, passphrases and PINs. - \param promptStr the prompt to display to the user + \param promptStr the prompt to display to the user - \sa result() for how to get the input back. - */ - void getHidden(const QString &promptStr); + \sa result() for how to get the input back. + */ + void getHidden(const QString &promptStr); - /** - Obtain one character from the user + /** + Obtain one character from the user - \sa resultChar() for how to get the input back. - */ - void getChar(); + \sa resultChar() for how to get the input back. + */ + void getChar(); - /** - Block waiting for user input. + /** + Block waiting for user input. - You may wish to use the finished() signal to - avoid blocking. - */ - void waitForFinished(); + You may wish to use the finished() signal to + avoid blocking. + */ + void waitForFinished(); - /** - Obtain the result of the user input. + /** + Obtain the result of the user input. - This method is usually called to obtain data - from the user that was requested by the getHidden() - call. - */ - SecureArray result() const; + This method is usually called to obtain data + from the user that was requested by the getHidden() + call. + */ + SecureArray result() const; - /** - Obtain the result of the user input. + /** + Obtain the result of the user input. - This method is usually called to obtain data - from the user that was requested by the getChar() - call. - */ - QChar resultChar() const; + This method is usually called to obtain data + from the user that was requested by the getChar() + call. + */ + QChar resultChar() const; Q_SIGNALS: - /** - Emitted when the user input activity has been - completed. + /** + Emitted when the user input activity has been + completed. - This corresponds to the provision of a string - for getHidden() or a single character for getChar(). + This corresponds to the provision of a string + for getHidden() or a single character for getChar(). - \sa waitForFinished - */ - void finished(); + \sa waitForFinished + */ + void finished(); private: - Q_DISABLE_COPY(ConsolePrompt) + Q_DISABLE_COPY(ConsolePrompt) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; class AbstractLogDevice; @@ -953,97 +950,99 @@ */ class QCA_EXPORT Logger : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - The severity of the message - - This information may be used by the log device to determine - what the appropriate action is. - */ - enum Severity - { - Quiet = 0, ///< Quiet: turn of logging - Emergency = 1, ///< Emergency: system is unusable - Alert = 2, ///< Alert: action must be taken immediately - Critical = 3, ///< Critical: critical conditions - Error = 4, ///< Error: error conditions - Warning = 5, ///< Warning: warning conditions - Notice = 6, ///< Notice: normal but significant condition - Information = 7, ///< Informational: informational messages - Debug = 8 ///< Debug: debug-level messages - }; - - /** - Get the current logging level - - \return Current level - */ - inline Severity level() const { return m_logLevel; } - - /** - Set the current logging level - - \param level new logging level - - Only severities less or equal than the log level one will be logged - */ - void setLevel(Severity level); - - /** - Log a message to all available log devices - - \param message the text to log - */ - void logTextMessage(const QString &message, Severity = Information); - - /** - Log a binary blob to all available log devices - - \param blob the information to log - - \note how this is handled is quite logger specific. For - example, it might be logged as a binary, or it might be - encoded in some way - */ - void logBinaryMessage(const QByteArray &blob, Severity = Information); - - /** - Add an AbstractLogDevice subclass to the existing list of loggers - - \param logger the LogDevice to add - */ - void registerLogDevice(AbstractLogDevice *logger); - - /** - Remove an AbstractLogDevice subclass from the existing list of loggers - - \param loggerName the name of the LogDevice to remove - - \note If there are several log devices with the same name, all will be removed. - */ - void unregisterLogDevice(const QString &loggerName); - - /** - Get a list of the names of all registered log devices - */ - QStringList currentLogDevices() const; + /** + The severity of the message + + This information may be used by the log device to determine + what the appropriate action is. + */ + enum Severity { + Quiet = 0, ///< Quiet: turn of logging + Emergency = 1, ///< Emergency: system is unusable + Alert = 2, ///< Alert: action must be taken immediately + Critical = 3, ///< Critical: critical conditions + Error = 4, ///< Error: error conditions + Warning = 5, ///< Warning: warning conditions + Notice = 6, ///< Notice: normal but significant condition + Information = 7, ///< Informational: informational messages + Debug = 8 ///< Debug: debug-level messages + }; + + /** + Get the current logging level + + \return Current level + */ + inline Severity level() const + { + return m_logLevel; + } + + /** + Set the current logging level + + \param level new logging level + + Only severities less or equal than the log level one will be logged + */ + void setLevel(Severity level); + + /** + Log a message to all available log devices + + \param message the text to log + */ + void logTextMessage(const QString &message, Severity = Information); + + /** + Log a binary blob to all available log devices + + \param blob the information to log + + \note how this is handled is quite logger specific. For + example, it might be logged as a binary, or it might be + encoded in some way + */ + void logBinaryMessage(const QByteArray &blob, Severity = Information); + + /** + Add an AbstractLogDevice subclass to the existing list of loggers + + \param logger the LogDevice to add + */ + void registerLogDevice(AbstractLogDevice *logger); + + /** + Remove an AbstractLogDevice subclass from the existing list of loggers + + \param loggerName the name of the LogDevice to remove + + \note If there are several log devices with the same name, all will be removed. + */ + void unregisterLogDevice(const QString &loggerName); + + /** + Get a list of the names of all registered log devices + */ + QStringList currentLogDevices() const; private: - Q_DISABLE_COPY(Logger) + Q_DISABLE_COPY(Logger) - friend class Global; + friend class Global; - /** - Create a new message logger - */ - Logger(); + /** + Create a new message logger + */ + Logger(); - ~Logger(); + ~Logger(); - QStringList m_loggerNames; - QList m_loggers; - Severity m_logLevel; + QStringList m_loggerNames; + QList m_loggers; + Severity m_logLevel; }; /** @@ -1055,55 +1054,55 @@ */ class QCA_EXPORT AbstractLogDevice : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - The name of this log device - */ - QString name() const; + /** + The name of this log device + */ + QString name() const; - /** - Log a message + /** + Log a message - The default implementation does nothing - you should - override this method in your subclass to do whatever - logging is required + The default implementation does nothing - you should + override this method in your subclass to do whatever + logging is required - \param message the message to log - \param severity the severity level of the message - */ - virtual void logTextMessage(const QString &message, Logger::Severity severity); + \param message the message to log + \param severity the severity level of the message + */ + virtual void logTextMessage(const QString &message, Logger::Severity severity); - /** - Log a binary blob + /** + Log a binary blob - The default implementation does nothing - you should - override this method in your subclass to do whatever - logging is required + The default implementation does nothing - you should + override this method in your subclass to do whatever + logging is required - \param blob the message (as a byte array) to log - \param severity the severity level of the message - */ - virtual void logBinaryMessage(const QByteArray &blob, Logger::Severity severity); + \param blob the message (as a byte array) to log + \param severity the severity level of the message + */ + virtual void logBinaryMessage(const QByteArray &blob, Logger::Severity severity); protected: - /** - Create a new message logger + /** + Create a new message logger - \param name the name of this log device - \param parent the parent for this logger - */ - explicit AbstractLogDevice(const QString &name, QObject *parent = 0); + \param name the name of this log device + \param parent the parent for this logger + */ + explicit AbstractLogDevice(const QString &name, QObject *parent = 0); - virtual ~AbstractLogDevice() = 0; + virtual ~AbstractLogDevice() = 0; private: - Q_DISABLE_COPY(AbstractLogDevice) + Q_DISABLE_COPY(AbstractLogDevice) - class Private; - Private *d; + class Private; + Private *d; - QString m_name; + QString m_name; }; } diff --git a/include/QtCrypto/qca_textfilter.h b/include/QtCrypto/qca_textfilter.h --- a/include/QtCrypto/qca_textfilter.h +++ b/include/QtCrypto/qca_textfilter.h @@ -35,123 +35,124 @@ #include "qca_core.h" -namespace QCA { +namespace QCA +{ /** \class TextFilter qca_textfilter.h QtCrypto Superclass for text based filtering algorithms This differs from Filter in that it has the concept - of an algorithm that works in two directions, and + of an algorithm that works in two directions, and supports operations on QString arguments. \ingroup UserAPI */ class QCA_EXPORT TextFilter : public Filter { public: - /** - Standard constructor + /** + Standard constructor - \param dir the Direction that this TextFilter - should use. - */ - TextFilter(Direction dir); + \param dir the Direction that this TextFilter + should use. + */ + TextFilter(Direction dir); - /** - Reset the TextFilter + /** + Reset the TextFilter - \param dir the Direction that this TextFilter - should use. - */ - void setup(Direction dir); + \param dir the Direction that this TextFilter + should use. + */ + void setup(Direction dir); - /** - The direction the TextFilter is set up to use - */ - Direction direction() const; + /** + The direction the TextFilter is set up to use + */ + Direction direction() const; - /** - Process an array in the "forward" direction, - returning an array + /** + Process an array in the "forward" direction, + returning an array - This method runs in the forward direction, so - for something like a Base64 encoding, it takes - the "native" array, and returns that array - encoded in base64. + This method runs in the forward direction, so + for something like a Base64 encoding, it takes + the "native" array, and returns that array + encoded in base64. - \param a the array to encode - */ - MemoryRegion encode(const MemoryRegion &a); + \param a the array to encode + */ + MemoryRegion encode(const MemoryRegion &a); - /** - Process an array in the "reverse" direction, - returning an array + /** + Process an array in the "reverse" direction, + returning an array - This method runs in the reverse direction, so - for something like a Base64 encoding, it takes - a Base64 encoded array, and returns the "native" - representation. + This method runs in the reverse direction, so + for something like a Base64 encoding, it takes + a Base64 encoded array, and returns the "native" + representation. - \param a the array to decode - */ - MemoryRegion decode(const MemoryRegion &a); + \param a the array to decode + */ + MemoryRegion decode(const MemoryRegion &a); - /** - Process an array in the "forward" direction, - returning a QString + /** + Process an array in the "forward" direction, + returning a QString - This is equivalent to encode(), except - that it returns a QString, rather than a - byte array. + This is equivalent to encode(), except + that it returns a QString, rather than a + byte array. - \param a the array to encode - */ - QString arrayToString(const MemoryRegion &a); + \param a the array to encode + */ + QString arrayToString(const MemoryRegion &a); - /** - Process an string in the "reverse" direction, - returning a byte array + /** + Process an string in the "reverse" direction, + returning a byte array - This is equivalent to decode(), except - that it takes a QString, rather than a - byte array. + This is equivalent to decode(), except + that it takes a QString, rather than a + byte array. - \param s the array to decode - */ - MemoryRegion stringToArray(const QString &s); + \param s the array to decode + */ + MemoryRegion stringToArray(const QString &s); - /** - Process a string in the "forward" direction, - returning a string + /** + Process a string in the "forward" direction, + returning a string - This is equivalent to encode(), except - that it takes and returns a QString, rather than - byte arrays. + This is equivalent to encode(), except + that it takes and returns a QString, rather than + byte arrays. - \param s the string to encode - */ - QString encodeString(const QString &s); + \param s the string to encode + */ + QString encodeString(const QString &s); - /** - Process a string in the "reverse" direction, - returning a string + /** + Process a string in the "reverse" direction, + returning a string - This is equivalent to decode(), except - that it takes and returns a QString, rather than - byte arrays. + This is equivalent to decode(), except + that it takes and returns a QString, rather than + byte arrays. - \param s the string to decode - */ - QString decodeString(const QString &s); + \param s the string to decode + */ + QString decodeString(const QString &s); protected: - /** - Internal state variable for the Direction - that the filter operates in - */ - Direction _dir; + /** + Internal state variable for the Direction + that the filter operates in + */ + Direction _dir; }; /** @@ -164,62 +165,62 @@ class QCA_EXPORT Hex : public TextFilter { public: - /** - Standard constructor - - \param dir the Direction that should be used. - - \note The direction can be changed using - the setup() call. - */ - Hex(Direction dir = Encode); - - /** - Reset the internal state. - - This is useful to reuse an existing Hex object - */ - virtual void clear(); - - /** - Process more data, returning the corresponding - encoded or decoded (depending on the Direction - set in the constructor or setup() call) representation. - - If you find yourself with code that only calls - this method once, you might be better off using - encode() or decode(). Similarly, if the data is - really a string, you might be better off using - arrayToString(), encodeString(), stringToArray() - or decodeString(). - - \param a the array containing data to process - */ - virtual MemoryRegion update(const MemoryRegion &a); - - /** - Complete the algorithm - - \return any remaining output. Because of the way - hexadecimal encoding works, this will return a - zero length array - any output will have been returned - from the update() call. - */ - virtual MemoryRegion final(); - - /** - Test if an update() or final() call succeeded. - - \return true if the previous call succeeded - */ - virtual bool ok() const; + /** + Standard constructor + + \param dir the Direction that should be used. + + \note The direction can be changed using + the setup() call. + */ + Hex(Direction dir = Encode); + + /** + Reset the internal state. + + This is useful to reuse an existing Hex object + */ + virtual void clear(); + + /** + Process more data, returning the corresponding + encoded or decoded (depending on the Direction + set in the constructor or setup() call) representation. + + If you find yourself with code that only calls + this method once, you might be better off using + encode() or decode(). Similarly, if the data is + really a string, you might be better off using + arrayToString(), encodeString(), stringToArray() + or decodeString(). + + \param a the array containing data to process + */ + virtual MemoryRegion update(const MemoryRegion &a); + + /** + Complete the algorithm + + \return any remaining output. Because of the way + hexadecimal encoding works, this will return a + zero length array - any output will have been returned + from the update() call. + */ + virtual MemoryRegion final(); + + /** + Test if an update() or final() call succeeded. + + \return true if the previous call succeeded + */ + virtual bool ok() const; private: - Q_DISABLE_COPY(Hex) + Q_DISABLE_COPY(Hex) - uchar val; - bool partial; - bool _ok; + uchar val; + bool partial; + bool _ok; }; /** @@ -232,94 +233,94 @@ class QCA_EXPORT Base64 : public TextFilter { public: - /** - Standard constructor - - \param dir the Direction that should be used. - - \note The direction can be changed using - the setup() call. - */ - Base64(Direction dir = Encode); - - /** - Returns true if line breaks are enabled - */ - bool lineBreaksEnabled() const; - - /** - Returns the line break column - */ - int lineBreaksColumn() const; - - /** - Sets line break mode. If enabled, linebreaks will be - added to encoded output or accepted in encoded input. - If disabled, linebreaks in encoded input will cause - a failure to decode. The default is disabled. - - \param b whether to enable line breaks (true) or disable line breaks (false) - */ - void setLineBreaksEnabled(bool b); - - /** - Sets the column that linebreaks should be inserted at - when encoding. - - \param column the column number that line breaks should be inserted at. - */ - void setLineBreaksColumn(int column); - - /** - Reset the internal state. This is useful to - reuse an existing Base64 object - */ - virtual void clear(); - - /** - Process more data, returning the corresponding - encoded or decoded (depending on the Direction - set in the constructor or setup() call) representation. - - If you find yourself with code that only calls - this method once, you might be better off using - encode() or decode(). Similarly, if the data is - really a string, you might be better off using - arrayToString(), encodeString(), stringToArray() - or decodeString(). - - \param a the array containing data to process - */ - virtual MemoryRegion update(const MemoryRegion &a); - - /** - Complete the algorithm - - \return any remaining output. Because of the way - Base64 encoding works, you will get either an - empty array, or an array containing one or two - "=" (equals, 0x3D) characters. - */ - virtual MemoryRegion final(); - - /** - Test if an update() or final() call succeeded. - - \return true if the previous call succeeded - */ - virtual bool ok() const; + /** + Standard constructor + + \param dir the Direction that should be used. + + \note The direction can be changed using + the setup() call. + */ + Base64(Direction dir = Encode); + + /** + Returns true if line breaks are enabled + */ + bool lineBreaksEnabled() const; + + /** + Returns the line break column + */ + int lineBreaksColumn() const; + + /** + Sets line break mode. If enabled, linebreaks will be + added to encoded output or accepted in encoded input. + If disabled, linebreaks in encoded input will cause + a failure to decode. The default is disabled. + + \param b whether to enable line breaks (true) or disable line breaks (false) + */ + void setLineBreaksEnabled(bool b); + + /** + Sets the column that linebreaks should be inserted at + when encoding. + + \param column the column number that line breaks should be inserted at. + */ + void setLineBreaksColumn(int column); + + /** + Reset the internal state. This is useful to + reuse an existing Base64 object + */ + virtual void clear(); + + /** + Process more data, returning the corresponding + encoded or decoded (depending on the Direction + set in the constructor or setup() call) representation. + + If you find yourself with code that only calls + this method once, you might be better off using + encode() or decode(). Similarly, if the data is + really a string, you might be better off using + arrayToString(), encodeString(), stringToArray() + or decodeString(). + + \param a the array containing data to process + */ + virtual MemoryRegion update(const MemoryRegion &a); + + /** + Complete the algorithm + + \return any remaining output. Because of the way + Base64 encoding works, you will get either an + empty array, or an array containing one or two + "=" (equals, 0x3D) characters. + */ + virtual MemoryRegion final(); + + /** + Test if an update() or final() call succeeded. + + \return true if the previous call succeeded + */ + virtual bool ok() const; private: - Q_DISABLE_COPY(Base64) + Q_DISABLE_COPY(Base64) - QByteArray partial; - bool _ok; - int col; - bool _lb_enabled; - int _lb_column; + QByteArray partial; + bool _ok; + int col; + bool _lb_enabled; + int _lb_column; - class Private; - Private *d; + class Private; + Private *d; }; } diff --git a/include/QtCrypto/qca_tools.h b/include/QtCrypto/qca_tools.h --- a/include/QtCrypto/qca_tools.h +++ b/include/QtCrypto/qca_tools.h @@ -73,7 +73,8 @@ */ QCA_EXPORT void *qca_secure_realloc(void *p, int bytes); -namespace QCA { +namespace QCA +{ /** \class MemoryRegion qca_tools.h QtCrypto @@ -90,212 +91,212 @@ class QCA_EXPORT MemoryRegion { public: - MemoryRegion(); + MemoryRegion(); + + /** + Constructs a new Memory Region from a null terminated + character array + + \param str pointer to the array of data to copy + */ + MemoryRegion(const char *str); + + /** + Constructs a new MemoryRegion from the data in a + byte array + + \param from the QByteArray to copy from + */ + MemoryRegion(const QByteArray &from); + + /** + Standard copy constructor + + \param from the MemoryRegion to copy from + */ + MemoryRegion(const MemoryRegion &from); + ~MemoryRegion(); + + /** + Standard assignment operator + + \param from the MemoryRegion to copy from + */ + MemoryRegion &operator=(const MemoryRegion &from); + + /** + Standard assignment operator + + \param from the QByteArray to copy from + */ + MemoryRegion &operator=(const QByteArray &from); + + /** + Test if the MemoryRegion is null (i.e. was created + as a null array, and hasn't been resized). + + This is probably not what you are trying to do. If + you are trying to determine whether there are any + bytes in the array, use isEmpty() instead. + */ + bool isNull() const; + + /** + Test if the MemoryRegion is using secure memory, or not. + + In this context, memory is secure if it will not be paged + out to disk. + + \return true if the memory region is secure + */ + bool isSecure() const; - /** - Constructs a new Memory Region from a null terminated - character array - - \param str pointer to the array of data to copy - */ - MemoryRegion(const char *str); - - /** - Constructs a new MemoryRegion from the data in a - byte array - - \param from the QByteArray to copy from - */ - MemoryRegion(const QByteArray &from); - - /** - Standard copy constructor - - \param from the MemoryRegion to copy from - */ - MemoryRegion(const MemoryRegion &from); - ~MemoryRegion(); - - /** - Standard assignment operator - - \param from the MemoryRegion to copy from - */ - MemoryRegion & operator=(const MemoryRegion &from); - - /** - Standard assignment operator - - \param from the QByteArray to copy from - */ - MemoryRegion & operator=(const QByteArray &from); - - /** - Test if the MemoryRegion is null (i.e. was created - as a null array, and hasn't been resized). - - This is probably not what you are trying to do. If - you are trying to determine whether there are any - bytes in the array, use isEmpty() instead. - */ - bool isNull() const; - - /** - Test if the MemoryRegion is using secure memory, or not. - - In this context, memory is secure if it will not be paged - out to disk. - - \return true if the memory region is secure - */ - bool isSecure() const; - - /** - Convert this memory region to a byte array. - - \note For secure data, this will make it insecure - - \sa data() and constData() for other ways to convert - to an "accessible" format. - */ - QByteArray toByteArray() const; - - /** - Returns true if the size of the memory region is zero. - */ - bool isEmpty() const; - - /** - Returns the number of bytes in the memory region. - */ - int size() const; - - /** - Convert the contents of the memory region to - a C-compatible character array. This consists - of size() bytes, followed by a null terminator. - - \sa toByteArray for an alternative approach. - \sa constData, which is equivalent to this method, but avoids - the possibility that the compiler picks the wrong version. - */ - const char *data() const; - - /** - Convert the contents of the memory region to - a C-compatible character array. This consists - of size() bytes, followed by a null terminator. - - \sa toByteArray for an alternative approach. - \sa data which is equivalent to this method - */ - const char *constData() const; - - /** - Obtain the value of the memory location at the specified - position. - - \param index the offset into the memory region. - - \note The contents of a memory region are between - 0 and size()-1. The content at position size() is - always a null terminator. - */ - const char & at(int index) const; + /** + Convert this memory region to a byte array. + + \note For secure data, this will make it insecure + + \sa data() and constData() for other ways to convert + to an "accessible" format. + */ + QByteArray toByteArray() const; + + /** + Returns true if the size of the memory region is zero. + */ + bool isEmpty() const; + + /** + Returns the number of bytes in the memory region. + */ + int size() const; + + /** + Convert the contents of the memory region to + a C-compatible character array. This consists + of size() bytes, followed by a null terminator. + + \sa toByteArray for an alternative approach. + \sa constData, which is equivalent to this method, but avoids + the possibility that the compiler picks the wrong version. + */ + const char *data() const; + + /** + Convert the contents of the memory region to + a C-compatible character array. This consists + of size() bytes, followed by a null terminator. + + \sa toByteArray for an alternative approach. + \sa data which is equivalent to this method + */ + const char *constData() const; + + /** + Obtain the value of the memory location at the specified + position. + + \param index the offset into the memory region. + + \note The contents of a memory region are between + 0 and size()-1. The content at position size() is + always a null terminator. + */ + const char &at(int index) const; protected: - /** - Create a memory region, optionally using secure - storage. - - \param secure if this is true, the memory region - will use secure storage. - - \note This will create a memory region without - any content (i.e. both isNull() and isEmpty() will - return true. - */ - MemoryRegion(bool secure); - - /** - Create a memory region, optionally using secure - storage. - - \param size the number of bytes in the memory - region. - \param secure if this is true, the memory region - will use secure storage. - */ - MemoryRegion(int size, bool secure); - - /** - Create a memory region, optionally using secure - storage. - - This constructor variant allows you to - initialize the memory region from an existing - array. - - \param from the byte array to copy from. - \param secure if this is true, the memory region - will use secure storage. - */ - MemoryRegion(const QByteArray &from, bool secure); - - /** - Convert the contents of the memory region to - a C-compatible character array. This consists - of size() bytes, followed by a null terminator. - */ - char *data(); - - /** - Obtain the value of the memory location at the specified - position. - - \param index the offset into the memory region. - - \note The contents of a memory region are between - 0 and size()-1. The content at position size() is - always a null terminator. - */ - char & at(int index); - - /** - Resize the memory region to the specified size. - - \param size the new size of the region. - */ - bool resize(int size); - - /** - Modify the memory region to match a specified - byte array. This resizes the memory region - as required to match the byte array size. - - \param from the byte array to copy from. - \param secure if this is true, the memory region - will use secure storage. - */ - void set(const QByteArray &from, bool secure); - - /** - Convert the memory region to use the specified - memory type. - - This may involve copying data from secure to - insecure storage, or from insecure to secure - storage. - - \param secure if true, use secure memory; otherwise - use insecure memory. - */ - void setSecure(bool secure); + /** + Create a memory region, optionally using secure + storage. + + \param secure if this is true, the memory region + will use secure storage. + + \note This will create a memory region without + any content (i.e. both isNull() and isEmpty() will + return true. + */ + MemoryRegion(bool secure); + + /** + Create a memory region, optionally using secure + storage. + + \param size the number of bytes in the memory + region. + \param secure if this is true, the memory region + will use secure storage. + */ + MemoryRegion(int size, bool secure); + + /** + Create a memory region, optionally using secure + storage. + + This constructor variant allows you to + initialize the memory region from an existing + array. + + \param from the byte array to copy from. + \param secure if this is true, the memory region + will use secure storage. + */ + MemoryRegion(const QByteArray &from, bool secure); + + /** + Convert the contents of the memory region to + a C-compatible character array. This consists + of size() bytes, followed by a null terminator. + */ + char *data(); + + /** + Obtain the value of the memory location at the specified + position. + + \param index the offset into the memory region. + + \note The contents of a memory region are between + 0 and size()-1. The content at position size() is + always a null terminator. + */ + char &at(int index); + + /** + Resize the memory region to the specified size. + + \param size the new size of the region. + */ + bool resize(int size); + + /** + Modify the memory region to match a specified + byte array. This resizes the memory region + as required to match the byte array size. + + \param from the byte array to copy from. + \param secure if this is true, the memory region + will use secure storage. + */ + void set(const QByteArray &from, bool secure); + + /** + Convert the memory region to use the specified + memory type. + + This may involve copying data from secure to + insecure storage, or from insecure to secure + storage. + + \param secure if true, use secure memory; otherwise + use insecure memory. + */ + void setSecure(bool secure); private: - bool _secure; - class Private; - QSharedDataPointer d; + bool _secure; + class Private; + QSharedDataPointer d; }; /** @@ -316,231 +317,231 @@ class QCA_EXPORT SecureArray : public MemoryRegion { public: - /** - Construct a secure byte array, zero length - */ - SecureArray(); + /** + Construct a secure byte array, zero length + */ + SecureArray(); + + /** + Construct a secure byte array of the specified length - /** - Construct a secure byte array of the specified length + \param size the number of bytes in the array + \param ch the value every byte should be set to + */ + explicit SecureArray(int size, char ch = 0); - \param size the number of bytes in the array - \param ch the value every byte should be set to - */ - explicit SecureArray(int size, char ch = 0); + /** + Construct a secure byte array from a string - /** - Construct a secure byte array from a string + Note that this copies, rather than references the source array. - Note that this copies, rather than references the source array. + \param str the source of the data (as a null terminated string). + */ + SecureArray(const char *str); - \param str the source of the data (as a null terminated string). - */ - SecureArray(const char *str); + /** + Construct a secure byte array from a QByteArray - /** - Construct a secure byte array from a QByteArray + Note that this copies, rather than references the source array. - Note that this copies, rather than references the source array. + \param a the source of the data. - \param a the source of the data. + \sa operator=() + */ + SecureArray(const QByteArray &a); - \sa operator=() - */ - SecureArray(const QByteArray &a); + /** + Construct a secure byte array from a MemoryRegion - /** - Construct a secure byte array from a MemoryRegion + Note that this copies, rather than references the source array - Note that this copies, rather than references the source array + \param a the source of the data. - \param a the source of the data. + \sa operator=() + */ + SecureArray(const MemoryRegion &a); - \sa operator=() - */ - SecureArray(const MemoryRegion &a); + /** + Construct a (shallow) copy of another secure byte array - /** - Construct a (shallow) copy of another secure byte array + \param from the source of the data and length. + */ + SecureArray(const SecureArray &from); - \param from the source of the data and length. - */ - SecureArray(const SecureArray &from); + ~SecureArray(); - ~SecureArray(); + /** + Creates a reference, rather than a deep copy. - /** - Creates a reference, rather than a deep copy. + \param from the array to reference + */ + SecureArray &operator=(const SecureArray &from); - \param from the array to reference - */ - SecureArray & operator=(const SecureArray &from); + /** + Creates a copy, rather than references - /** - Creates a copy, rather than references + \param a the array to copy from + */ + SecureArray &operator=(const QByteArray &a); - \param a the array to copy from - */ - SecureArray & operator=(const QByteArray &a); + /** + Clears the contents of the array and makes it empty + */ + void clear(); - /** - Clears the contents of the array and makes it empty - */ - void clear(); + /** + Returns a reference to the byte at the index position - /** - Returns a reference to the byte at the index position + \param index the zero-based offset to obtain + */ + char &operator[](int index); - \param index the zero-based offset to obtain - */ - char & operator[](int index); + /** + Returns a reference to the byte at the index position - /** - Returns a reference to the byte at the index position + \param index the zero-based offset to obtain + */ + const char &operator[](int index) const; - \param index the zero-based offset to obtain - */ - const char & operator[](int index) const; + /** + Pointer to the data in the secure array - /** - 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(); - 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(); + /** + Pointer to the data in the secure array - /** - 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; - 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 - /** - 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 *constData() const; - 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 *constData() const; + /** + Returns a reference to the byte at the index position - /** - Returns a reference to the byte at the index position + \param index the zero-based offset to obtain + */ + char &at(int index); - \param index the zero-based offset to obtain - */ - char & at(int index); + /** + Returns a reference to the byte at the index position - /** - Returns a reference to the byte at the index position + \param index the zero-based offset to obtain + */ + const char &at(int index) const; - \param index the zero-based offset to obtain - */ - const char & at(int index) const; + /** + Returns the number of bytes in the array + */ + int size() const; - /** - Returns the number of bytes in the array - */ - int size() const; + /** + Test if the array contains any bytes. - /** - 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) - 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(int 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); - - /** - 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 - - \param a the array to append to this array - */ - SecureArray & append(const SecureArray &a); - - /** - Equality operator. Returns true if both arrays have the same - data (and the same length, of course). - - \param other the MemoryRegion to compare to - */ - bool operator==(const MemoryRegion &other) const; - - /** - Inequality operator. Returns true if both arrays have different - length, or the same length but different data. - - \param other the MemoryRegion to compare to - */ - inline bool operator!=(const MemoryRegion &other) const - { - return !(*this == other); - } - - /** - Append a secure byte array to the end of this array - - \param a the array to append to this array - */ - SecureArray & operator+=(const SecureArray &a); + \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(int 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); + + /** + 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 + + \param a the array to append to this array + */ + SecureArray &append(const SecureArray &a); + + /** + Equality operator. Returns true if both arrays have the same + data (and the same length, of course). + + \param other the MemoryRegion to compare to + */ + bool operator==(const MemoryRegion &other) const; + + /** + Inequality operator. Returns true if both arrays have different + length, or the same length but different data. + + \param other the MemoryRegion to compare to + */ + inline bool operator!=(const MemoryRegion &other) const + { + return !(*this == other); + } + + /** + Append a secure byte array to the end of this array + + \param a the array to append to this array + */ + SecureArray &operator+=(const SecureArray &a); protected: - /** - Assign the contents of a provided byte array to this - object. + /** + Assign the contents of a provided byte array to this + object. - \param from the byte array to copy - */ - void set(const SecureArray &from); + \param from the byte array to copy + */ + void set(const SecureArray &from); - /** - Assign the contents of a provided byte array to this - object. + /** + Assign the contents of a provided byte array to this + object. - \param from the byte array to copy - */ - void set(const QByteArray &from); + \param from the byte array to copy + */ + void set(const QByteArray &from); }; /** @@ -558,285 +559,283 @@ BigInteger provides arbitrary precision integers. \code -if ( BigInteger("3499543804349") == - BigInteger("38493290803248") + BigInteger( 343 ) ) +if ( BigInteger("3499543804349") == + BigInteger("38493290803248") + BigInteger( 343 ) ) { - // do something + // do something } \endcode \ingroup UserAPI */ class QCA_EXPORT BigInteger { public: - /** - Constructor. Creates a new BigInteger, initialised to zero. - */ - BigInteger(); + /** + Constructor. Creates a new BigInteger, initialised to zero. + */ + BigInteger(); - /** - \overload + /** + \overload - \param n an alternative integer initialisation value. - */ - BigInteger(int n); + \param n an alternative integer initialisation value. + */ + BigInteger(int n); - /** - \overload + /** + \overload - \param c an alternative initialisation value, encoded as a character array + \param c an alternative initialisation value, encoded as a character array - \code -BigInteger b ( "9890343" ); - \endcode - */ - BigInteger(const char *c); + \code + BigInteger b ( "9890343" ); + \endcode + */ + BigInteger(const char *c); - /** - \overload + /** + \overload - \param s an alternative initialisation value, encoded as a string - */ - BigInteger(const QString &s); + \param s an alternative initialisation value, encoded as a string + */ + BigInteger(const QString &s); - /** - \overload + /** + \overload - \param a an alternative initialisation value, encoded as SecureArray - */ - BigInteger(const QCA::SecureArray &a); + \param a an alternative initialisation value, encoded as SecureArray + */ + BigInteger(const QCA::SecureArray &a); - /** - \overload + /** + \overload - \param from an alternative initialisation value, encoded as a %BigInteger - */ - BigInteger(const BigInteger &from); + \param from an alternative initialisation value, encoded as a %BigInteger + */ + BigInteger(const BigInteger &from); - ~BigInteger(); + ~BigInteger(); - /** - Assignment operator + /** + Assignment operator - \param from the BigInteger to copy from + \param from the BigInteger to copy from - \code -BigInteger a; // a is zero -BigInteger b( 500 ); -a = b; // a is now 500 - \endcode - */ - BigInteger & operator=(const BigInteger &from); + \code + BigInteger a; // a is zero + BigInteger b( 500 ); + a = b; // a is now 500 + \endcode + */ + BigInteger &operator=(const BigInteger &from); - /** - \overload + /** + \overload - \param s the QString containing an integer representation + \param s the QString containing an integer representation - \sa bool fromString(const QString &s) + \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) - */ - BigInteger & operator=(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) + */ + BigInteger &operator=(const QString &s); - /** - Increment in place operator + /** + Increment in place operator - \param b the amount to increment by + \param b the amount to increment by - \code -BigInteger a; // a is zero -BigInteger b( 500 ); -a += b; // a is now 500 -a += b; // a is now 1000 - \endcode - */ - BigInteger & operator+=(const BigInteger &b); + \code + BigInteger a; // a is zero + BigInteger b( 500 ); + a += b; // a is now 500 + a += b; // a is now 1000 + \endcode + */ + BigInteger &operator+=(const BigInteger &b); - /** - Decrement in place operator + /** + Decrement in place operator - \param b the amount to decrement by + \param b the amount to decrement by - \code -BigInteger a; // a is zero -BigInteger b( 500 ); -a -= b; // a is now -500 -a -= b; // a is now -1000 - \endcode - */ - BigInteger & operator-=(const BigInteger &b); - - /** - Multiply in place operator + \code + BigInteger a; // a is zero + BigInteger b( 500 ); + a -= b; // a is now -500 + a -= b; // a is now -1000 + \endcode + */ + BigInteger &operator-=(const BigInteger &b); + + /** + Multiply in place operator - \param b the amount to multiply by - */ - BigInteger & operator*=(const BigInteger &b); + \param b the amount to multiply by + */ + BigInteger &operator*=(const BigInteger &b); - /** - Divide in place operator - - \param b the amount to divide by - */ - BigInteger & operator/=(const BigInteger &b); - - /** - Modulo in place operator - - \param b the amount to divide by - */ - BigInteger & operator%=(const BigInteger &b); - - /** - Output %BigInteger 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 SecureArray &a); - */ - QCA::SecureArray toArray() const; - - /** - Assign from an array. The input is expected to be a binary integer - in sign-extended network-byte-order. - - \param a a SecureArray that represents an integer - - \sa BigInteger(const SecureArray &a); - \sa SecureArray toArray() const; - */ - void fromArray(const QCA::SecureArray &a); - - /** - Convert %BigInteger to a QString - - \code -QString aString; -BigInteger 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 BigInteger(const QString &s) - \sa BigInteger & operator=(const QString &s) - */ - bool fromString(const QString &s); - - /** - Compare this value with another %BigInteger - - 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 BigInteger to compare with - - \return zero if the values are the same, negative if the argument - is less than the value of this BigInteger, and positive if the - argument value is greater than this BigInteger - - \code -BigInteger a( "400" ); -BigInteger b( "-400" ); -BigInteger 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 BigInteger &n) const; - - /** - Equality operator. Returns true if the two BigInteger values - are the same, including having the same sign. - - \param other the BigInteger to compare to - */ - inline bool operator==(const BigInteger &other) const - { - return (compare(other) == 0); - } - - /** - Inequality operator. Returns true if the two BigInteger values - are different in magnitude, sign or both. - - \param other the BigInteger to compare to - */ - inline bool operator!=(const BigInteger &other) const - { - return !(*this == other); - } - - /** - Less than or equal operator. Returns true if the BigInteger value - on the left hand side is equal to or less than the BigInteger - value on the right hand side. - - \param other the BigInteger to compare to - */ - inline bool operator<=(const BigInteger &other) const - { - return (compare(other) <= 0); - } - - /** - Greater than or equal operator. Returns true if the BigInteger - value on the left hand side is equal to or greater than the - BigInteger value on the right hand side. - - \param other the BigInteger to compare to - */ - inline bool operator>=(const BigInteger &other) const - { - return (compare(other) >= 0); - } - - /** - Less than operator. Returns true if the BigInteger value - on the left hand side is less than the BigInteger value - on the right hand side. - - \param other the BigInteger to compare to - */ - inline bool operator<(const BigInteger &other) const - { - return (compare(other) < 0); - } - - /** - Greater than operator. Returns true if the BigInteger value - on the left hand side is greater than the BigInteger value - on the right hand side. - - \param other the BigInteger to compare to - */ - inline bool operator>(const BigInteger &other) const - { - return (compare(other) > 0); - } + /** + Divide in place operator + + \param b the amount to divide by + */ + BigInteger &operator/=(const BigInteger &b); + + /** + Modulo in place operator + + \param b the amount to divide by + */ + BigInteger &operator%=(const BigInteger &b); + + /** + Output %BigInteger 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 SecureArray &a); + */ + QCA::SecureArray toArray() const; + + /** + Assign from an array. The input is expected to be a binary integer + in sign-extended network-byte-order. + + \param a a SecureArray that represents an integer + + \sa BigInteger(const SecureArray &a); + \sa SecureArray toArray() const; + */ + void fromArray(const QCA::SecureArray &a); + + /** + Convert %BigInteger to a QString + + \code + QString aString; + BigInteger 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 BigInteger(const QString &s) + \sa BigInteger & operator=(const QString &s) + */ + bool fromString(const QString &s); + + /** + Compare this value with another %BigInteger + + 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 BigInteger to compare with + + \return zero if the values are the same, negative if the argument + is less than the value of this BigInteger, and positive if the + argument value is greater than this BigInteger + + \code + BigInteger a( "400" ); + BigInteger b( "-400" ); + BigInteger 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 BigInteger &n) const; + + /** + Equality operator. Returns true if the two BigInteger values + are the same, including having the same sign. + + \param other the BigInteger to compare to + */ + inline bool operator==(const BigInteger &other) const + { + return (compare(other) == 0); + } + + /** + Inequality operator. Returns true if the two BigInteger values + are different in magnitude, sign or both. + + \param other the BigInteger to compare to + */ + inline bool operator!=(const BigInteger &other) const + { + return !(*this == other); + } + + /** + Less than or equal operator. Returns true if the BigInteger value + on the left hand side is equal to or less than the BigInteger + value on the right hand side. + + \param other the BigInteger to compare to + */ + inline bool operator<=(const BigInteger &other) const + { + return (compare(other) <= 0); + } + + /** + Greater than or equal operator. Returns true if the BigInteger + value on the left hand side is equal to or greater than the + BigInteger value on the right hand side. + + \param other the BigInteger to compare to + */ + inline bool operator>=(const BigInteger &other) const + { + return (compare(other) >= 0); + } + + /** + Less than operator. Returns true if the BigInteger value + on the left hand side is less than the BigInteger value + on the right hand side. + + \param other the BigInteger to compare to + */ + inline bool operator<(const BigInteger &other) const + { + return (compare(other) < 0); + } + + /** + Greater than operator. Returns true if the BigInteger value + on the left hand side is greater than the BigInteger value + on the right hand side. + + \param other the BigInteger to compare to + */ + inline bool operator>(const BigInteger &other) const + { + return (compare(other) > 0); + } private: - class Private; - QSharedDataPointer d; + class Private; + QSharedDataPointer d; }; - - /** Stream operator @@ -847,7 +846,6 @@ */ QCA_EXPORT QTextStream &operator<<(QTextStream &stream, const BigInteger &b); - } #endif diff --git a/include/QtCrypto/qcaprovider.h b/include/QtCrypto/qcaprovider.h --- a/include/QtCrypto/qcaprovider.h +++ b/include/QtCrypto/qcaprovider.h @@ -48,7 +48,7 @@ /** \defgroup ProviderAPI QCA provider API - This group of classes is not normally needed + This group of classes is not normally needed by application writers, but can be used to extend QCA if required */ @@ -67,10 +67,10 @@ \code class MyPlugin : public QObject, public QCAPlugin { - Q_OBJECT - Q_INTERFACES(QCAPlugin) + Q_OBJECT + Q_INTERFACES(QCAPlugin) public: - virtual Provider *createProvider() { ... } + virtual Provider *createProvider() { ... } }; \endcode @@ -82,20 +82,21 @@ class QCA_EXPORT QCAPlugin { public: - /** - Destructs the object - */ - virtual ~QCAPlugin() {} - - /** - Returns a newly allocated Provider instance. - */ - virtual QCA::Provider *createProvider() = 0; + /** + Destructs the object + */ + virtual ~QCAPlugin() {} + + /** + Returns a newly allocated Provider instance. + */ + virtual QCA::Provider *createProvider() = 0; }; Q_DECLARE_INTERFACE(QCAPlugin, "com.affinix.qca.Plugin/1.0") -namespace QCA { +namespace QCA +{ /** \class InfoContext qcaprovider.h QtCrypto @@ -109,29 +110,29 @@ */ class QCA_EXPORT InfoContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - */ - InfoContext(Provider *p) : BasicContext(p, QStringLiteral("info") ) {} - - /** - The hash algorithms supported by the provider - */ - virtual QStringList supportedHashTypes() const; - - /** - The cipher algorithms supported by the provider - */ - virtual QStringList supportedCipherTypes() const; - - /** - The mac algorithms supported by the provider - */ - virtual QStringList supportedMACTypes() const; + /** + Standard constructor + + \param p the provider associated with this context + */ + InfoContext(Provider *p) : BasicContext(p, QStringLiteral("info")) {} + + /** + The hash algorithms supported by the provider + */ + virtual QStringList supportedHashTypes() const; + + /** + The cipher algorithms supported by the provider + */ + virtual QStringList supportedCipherTypes() const; + + /** + The mac algorithms supported by the provider + */ + virtual QStringList supportedMACTypes() const; }; /** @@ -146,21 +147,21 @@ */ class QCA_EXPORT RandomContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the provider associated with this context - */ - RandomContext(Provider *p) : BasicContext(p, QStringLiteral("random")) {} + \param p the provider associated with this context + */ + RandomContext(Provider *p) : BasicContext(p, QStringLiteral("random")) {} - /** - Return an array of random bytes + /** + Return an array of random bytes - \param size the number of random bytes to return - */ - virtual SecureArray nextBytes(int size) = 0; + \param size the number of random bytes to return + */ + virtual SecureArray nextBytes(int size) = 0; }; /** @@ -175,32 +176,32 @@ */ class QCA_EXPORT HashContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - \param type the name of the type of hash provided by this context - */ - HashContext(Provider *p, const QString &type) : BasicContext(p, type) {} - - /** - Reset the object to its initial state - */ - virtual void clear() = 0; - - /** - Process a chunk of data - - \param a the input data to process - */ - virtual void update(const MemoryRegion &a) = 0; - - /** - Return the computed hash - */ - virtual MemoryRegion final() = 0; + /** + Standard constructor + + \param p the provider associated with this context + \param type the name of the type of hash provided by this context + */ + HashContext(Provider *p, const QString &type) : BasicContext(p, type) {} + + /** + Reset the object to its initial state + */ + virtual void clear() = 0; + + /** + Process a chunk of data + + \param a the input data to process + */ + virtual void update(const MemoryRegion &a) = 0; + + /** + Return the computed hash + */ + virtual MemoryRegion final() = 0; }; /** @@ -215,58 +216,58 @@ */ class QCA_EXPORT CipherContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - \param type the name of the type of cipher provided by this context - - \note type includes the name of the cipher (e.g. "aes256"), the operating - mode (e.g. "cbc" or "ofb") and the padding type (e.g. "pkcs7") if any. - */ - CipherContext(Provider *p, const QString &type) : BasicContext(p, type) {} - - /** - Set up the object for encrypt/decrypt - - \param dir the direction for the cipher (encryption/decryption) - \param key the symmetric key to use for the cipher - \param iv the initialization vector to use for the cipher (not used in ECB mode) - \param tag the AuthTag to use (only for GCM and CCM modes) - */ - virtual void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag) = 0; - - /** - Returns the KeyLength for this cipher - */ - virtual KeyLength keyLength() const = 0; - - /** - Returns the block size for this cipher - */ - virtual int blockSize() const = 0; - - /** - Returns the authentication tag for this cipher - */ - virtual AuthTag tag() const = 0; - - /** - Process a chunk of data. Returns true if successful. - - \param in the input data to process - \param out pointer to an array that should store the result - */ - virtual bool update(const SecureArray &in, SecureArray *out) = 0; - - /** - Finish the cipher processing. Returns true if successful. - - \param out pointer to an array that should store the result - */ - virtual bool final(SecureArray *out) = 0; + /** + Standard constructor + + \param p the provider associated with this context + \param type the name of the type of cipher provided by this context + + \note type includes the name of the cipher (e.g. "aes256"), the operating + mode (e.g. "cbc" or "ofb") and the padding type (e.g. "pkcs7") if any. + */ + CipherContext(Provider *p, const QString &type) : BasicContext(p, type) {} + + /** + Set up the object for encrypt/decrypt + + \param dir the direction for the cipher (encryption/decryption) + \param key the symmetric key to use for the cipher + \param iv the initialization vector to use for the cipher (not used in ECB mode) + \param tag the AuthTag to use (only for GCM and CCM modes) + */ + virtual void setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag) = 0; + + /** + Returns the KeyLength for this cipher + */ + virtual KeyLength keyLength() const = 0; + + /** + Returns the block size for this cipher + */ + virtual int blockSize() const = 0; + + /** + Returns the authentication tag for this cipher + */ + virtual AuthTag tag() const = 0; + + /** + Process a chunk of data. Returns true if successful. + + \param in the input data to process + \param out pointer to an array that should store the result + */ + virtual bool update(const SecureArray &in, SecureArray *out) = 0; + + /** + Finish the cipher processing. Returns true if successful. + + \param out pointer to an array that should store the result + */ + virtual bool final(SecureArray *out) = 0; }; /** @@ -282,52 +283,52 @@ */ class QCA_EXPORT MACContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - \param p the provider associated with this context - \param type the name of the type of MAC algorithm provided by this context - */ - MACContext(Provider *p, const QString &type) : BasicContext(p, type) {} + /** + Standard constructor + \param p the provider associated with this context + \param type the name of the type of MAC algorithm provided by this context + */ + MACContext(Provider *p, const QString &type) : BasicContext(p, type) {} - /** - Set up the object for hashing + /** + Set up the object for hashing - \param key the key to use with the MAC. - */ - virtual void setup(const SymmetricKey &key) = 0; + \param key the key to use with the MAC. + */ + virtual void setup(const SymmetricKey &key) = 0; - /** - Returns the KeyLength for this MAC algorithm - */ - virtual KeyLength keyLength() const = 0; + /** + Returns the KeyLength for this MAC algorithm + */ + virtual KeyLength keyLength() const = 0; - /** - Process a chunk of data + /** + Process a chunk of data - \param in the input data to process - */ - virtual void update(const MemoryRegion &in) = 0; + \param in the input data to process + */ + virtual void update(const MemoryRegion &in) = 0; - /** - Compute the result after processing all data + /** + Compute the result after processing all data - \param out pointer to an array that should store the result - */ - virtual void final(MemoryRegion *out) = 0; + \param out pointer to an array that should store the result + */ + virtual void final(MemoryRegion *out) = 0; protected: - /** - Returns a KeyLength that supports any length - */ - KeyLength anyKeyLength() const - { - // this is used instead of a default implementation to make sure that - // provider authors think about it, at least a bit. - // See Meyers, Effective C++, Effective C++ (2nd Ed), Item 36 - return KeyLength( 0, INT_MAX, 1 ); - } + /** + Returns a KeyLength that supports any length + */ + KeyLength anyKeyLength() const + { + // this is used instead of a default implementation to make sure that + // provider authors think about it, at least a bit. + // See Meyers, Effective C++, Effective C++ (2nd Ed), Item 36 + return KeyLength(0, INT_MAX, 1); + } }; /** @@ -343,40 +344,40 @@ */ class QCA_EXPORT KDFContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - \param type the name of the KDF provided by this context (including algorithm) - */ - KDFContext(Provider *p, const QString &type) : BasicContext(p, type) {} - - /** - Create a key and return it - - \param secret the secret part (typically password) - \param salt the salt / initialization vector - \param keyLength the length of the key to be produced - \param iterationCount the number of iterations of the derivation algorith, - */ - virtual SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount) = 0; - - /** - Create a key and return it - - \param secret the secret part (typically password) - \param salt the salt / initialization vector - \param keyLength the length of the key to be produced - \param msecInterval the maximum time to compute the key, in milliseconds - \param iterationCount a pointer to store the number of iterations of the derivation algorithm, - */ - virtual SymmetricKey makeKey(const SecureArray &secret, - const InitializationVector &salt, - unsigned int keyLength, - int msecInterval, - unsigned int *iterationCount) = 0; + /** + Standard constructor + + \param p the provider associated with this context + \param type the name of the KDF provided by this context (including algorithm) + */ + KDFContext(Provider *p, const QString &type) : BasicContext(p, type) {} + + /** + Create a key and return it + + \param secret the secret part (typically password) + \param salt the salt / initialization vector + \param keyLength the length of the key to be produced + \param iterationCount the number of iterations of the derivation algorith, + */ + virtual SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount) = 0; + + /** + Create a key and return it + + \param secret the secret part (typically password) + \param salt the salt / initialization vector + \param keyLength the length of the key to be produced + \param msecInterval the maximum time to compute the key, in milliseconds + \param iterationCount a pointer to store the number of iterations of the derivation algorithm, + */ + virtual SymmetricKey makeKey(const SecureArray &secret, + const InitializationVector &salt, + unsigned int keyLength, + int msecInterval, + unsigned int *iterationCount) = 0; }; /** @@ -391,26 +392,26 @@ */ class QCA_EXPORT HKDFContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - \param type the name of the HKDF provided by this context (including algorithm) - */ - HKDFContext(Provider *p, const QString &type) : BasicContext(p, type) {} - - /** - Create a key and return it - - \param secret the secret part (typically password) - \param salt the salt / initialization vector - \param info the info / initialization vector - \param keyLength the length of the key to be produced - */ - virtual SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, - const InitializationVector &info, unsigned int keyLength) = 0; + /** + Standard constructor + + \param p the provider associated with this context + \param type the name of the HKDF provided by this context (including algorithm) + */ + HKDFContext(Provider *p, const QString &type) : BasicContext(p, type) {} + + /** + Create a key and return it + + \param secret the secret part (typically password) + \param salt the salt / initialization vector + \param info the info / initialization vector + \param keyLength the length of the key to be produced + */ + virtual SymmetricKey makeKey(const SecureArray &secret, const InitializationVector &salt, + const InitializationVector &info, unsigned int keyLength) = 0; }; /** @@ -425,56 +426,56 @@ */ class QCA_EXPORT DLGroupContext : public Provider::Context { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the provider associated with this context - */ - DLGroupContext(Provider *p) : Provider::Context(p, QStringLiteral("dlgroup")) {} + \param p the provider associated with this context + */ + DLGroupContext(Provider *p) : Provider::Context(p, QStringLiteral("dlgroup")) {} - /** - The DLGroupSets supported by this object - */ - virtual QList supportedGroupSets() const = 0; + /** + The DLGroupSets supported by this object + */ + virtual QList supportedGroupSets() const = 0; - /** - Returns true if there is a result to obtain - */ - virtual bool isNull() const = 0; + /** + Returns true if there is a result to obtain + */ + virtual bool isNull() const = 0; - /** - Attempt to create P, Q, and G values from the specified group set + /** + Attempt to create P, Q, and G values from the specified group set - If \a block is true, then this function blocks until completion. - Otherwise, this function returns immediately and finished() is - emitted when the operation completes. + If \a block is true, then this function blocks until completion. + Otherwise, this function returns immediately and finished() is + emitted when the operation completes. - If an error occurs during generation, then the operation will - complete and isNull() will return true. + If an error occurs during generation, then the operation will + complete and isNull() will return true. - \param set the group set to generate the key from - \param block whether to block (true) or not (false) - */ - virtual void fetchGroup(DLGroupSet set, bool block) = 0; + \param set the group set to generate the key from + \param block whether to block (true) or not (false) + */ + virtual void fetchGroup(DLGroupSet set, bool block) = 0; - /** - Obtain the result of the operation. Ensure isNull() returns false - before calling this function. + /** + Obtain the result of the operation. Ensure isNull() returns false + before calling this function. - \param p the P value - \param q the Q value - \param g the G value - */ - virtual void getResult(BigInteger *p, BigInteger *q, BigInteger *g) const = 0; + \param p the P value + \param q the Q value + \param g the G value + */ + virtual void getResult(BigInteger *p, BigInteger *q, BigInteger *g) const = 0; Q_SIGNALS: - /** - Emitted when the fetchGroup() operation completes in non-blocking - mode. - */ - void finished(); + /** + Emitted when the fetchGroup() operation completes in non-blocking + mode. + */ + void finished(); }; /** @@ -490,135 +491,135 @@ */ class QCA_EXPORT PKeyBase : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the Provider associated with this context - \param type type of key provided by this context - */ - PKeyBase(Provider *p, const QString &type); - - /** - Returns true if this object is not valid. This is the default - state, and the object may also become this state if a conversion - or generation function fails. - */ - virtual bool isNull() const = 0; - - /** - Returns the type of public key - */ - virtual PKey::Type type() const = 0; - - /** - Returns true if this is a private key, otherwise false - */ - virtual bool isPrivate() const = 0; - - /** - Returns true if the components of this key are accessible and - whether it can be serialized into an output format. Private keys - from a smart card device will often not be exportable. - */ - virtual bool canExport() const = 0; - - /** - If the key is a private key, this function will convert it into a - public key (all private key data includes the public data as well, - which is why this is possible). If the key is already a public - key, then this function has no effect. - */ - virtual void convertToPublic() = 0; - - /** - Returns the number of bits in the key - */ - virtual int bits() const = 0; - - /** - Returns the maximum number of bytes that can be encrypted by this - key - - \param alg the algorithm to be used for encryption - */ - virtual int maximumEncryptSize(EncryptionAlgorithm alg) const; - - /** - Encrypt data - - \param in the input data to encrypt - \param alg the encryption algorithm to use - */ - virtual SecureArray encrypt(const SecureArray &in, EncryptionAlgorithm alg); - - /** - Decrypt data - - \param in the input data to decrypt - \param out pointer to an array to store the plaintext result - \param alg the encryption algorithm used to generate the input - data - */ - virtual bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg); - - /** - Begin a signing operation - - \param alg the signature algorithm to use - \param format the signature format to use - */ - virtual void startSign(SignatureAlgorithm alg, SignatureFormat format); - - /** - Begin a verify operation - - \param alg the signature algorithm used by the input signature - \param format the signature format used by the input signature - */ - virtual void startVerify(SignatureAlgorithm alg, SignatureFormat format); - - /** - Process the plaintext input data for either signing or verifying, - whichever operation is active. - - \param in the input data to process - */ - virtual void update(const MemoryRegion &in); - - /** - Complete a signing operation, and return the signature value - - If there is an error signing, an empty array is returned. - */ - virtual QByteArray endSign(); - - /** - Complete a verify operation, and return true if successful - - If there is an error verifying, this function returns false. - - \param sig the signature to verify with the input data - */ - virtual bool endVerify(const QByteArray &sig); - - /** - Compute a symmetric key based on this private key and some other - public key + /** + Standard constructor + + \param p the Provider associated with this context + \param type type of key provided by this context + */ + PKeyBase(Provider *p, const QString &type); + + /** + Returns true if this object is not valid. This is the default + state, and the object may also become this state if a conversion + or generation function fails. + */ + virtual bool isNull() const = 0; + + /** + Returns the type of public key + */ + virtual PKey::Type type() const = 0; + + /** + Returns true if this is a private key, otherwise false + */ + virtual bool isPrivate() const = 0; + + /** + Returns true if the components of this key are accessible and + whether it can be serialized into an output format. Private keys + from a smart card device will often not be exportable. + */ + virtual bool canExport() const = 0; + + /** + If the key is a private key, this function will convert it into a + public key (all private key data includes the public data as well, + which is why this is possible). If the key is already a public + key, then this function has no effect. + */ + virtual void convertToPublic() = 0; + + /** + Returns the number of bits in the key + */ + virtual int bits() const = 0; + + /** + Returns the maximum number of bytes that can be encrypted by this + key + + \param alg the algorithm to be used for encryption + */ + virtual int maximumEncryptSize(EncryptionAlgorithm alg) const; + + /** + Encrypt data + + \param in the input data to encrypt + \param alg the encryption algorithm to use + */ + virtual SecureArray encrypt(const SecureArray &in, EncryptionAlgorithm alg); + + /** + Decrypt data + + \param in the input data to decrypt + \param out pointer to an array to store the plaintext result + \param alg the encryption algorithm used to generate the input + data + */ + virtual bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg); + + /** + Begin a signing operation + + \param alg the signature algorithm to use + \param format the signature format to use + */ + virtual void startSign(SignatureAlgorithm alg, SignatureFormat format); + + /** + Begin a verify operation + + \param alg the signature algorithm used by the input signature + \param format the signature format used by the input signature + */ + virtual void startVerify(SignatureAlgorithm alg, SignatureFormat format); + + /** + Process the plaintext input data for either signing or verifying, + whichever operation is active. + + \param in the input data to process + */ + virtual void update(const MemoryRegion &in); + + /** + Complete a signing operation, and return the signature value + + If there is an error signing, an empty array is returned. + */ + virtual QByteArray endSign(); + + /** + Complete a verify operation, and return true if successful + + If there is an error verifying, this function returns false. + + \param sig the signature to verify with the input data + */ + virtual bool endVerify(const QByteArray &sig); + + /** + Compute a symmetric key based on this private key and some other + public key - Essentially for Diffie-Hellman only. - - \param theirs the other side (public key) to be used for key generation. - */ - virtual SymmetricKey deriveKey(const PKeyBase &theirs); + Essentially for Diffie-Hellman only. + + \param theirs the other side (public key) to be used for key generation. + */ + virtual SymmetricKey deriveKey(const PKeyBase &theirs); Q_SIGNALS: - /** - Emitted when an asynchronous operation completes on this key. - Such operations will be documented that they emit this signal. - */ - void finished(); + /** + Emitted when an asynchronous operation completes on this key. + Such operations will be documented that they emit this signal. + */ + void finished(); }; /** @@ -634,74 +635,74 @@ */ class QCA_EXPORT RSAContext : public PKeyBase { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - */ - RSAContext(Provider *p) : PKeyBase(p, QStringLiteral("rsa")) {} - - /** - Generate an RSA private key - - If \a block is true, then this function blocks until completion. - Otherwise, this function returns immediately and finished() is - emitted when the operation completes. - - If an error occurs during generation, then the operation will - complete and isNull() will return true. - - \param bits the length of the key to generate, in bits - \param exp the exponent to use for generation - \param block whether to use blocking mode - */ - virtual void createPrivate(int bits, int exp, bool block) = 0; - - /** - Create an RSA private key based on the five components - - \param n the N parameter - \param e the public exponent - \param p the P parameter - \param q the Q parameter - \param d the D parameter - */ - virtual void createPrivate(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d) = 0; - - /** - Create an RSA public key based on the two public components - - \param n the N parameter - \param e the public exponent - */ - virtual void createPublic(const BigInteger &n, const BigInteger &e) = 0; - - /** - Returns the public N component of this RSA key - */ - virtual BigInteger n() const = 0; - - /** - Returns the public E component of this RSA key - */ - virtual BigInteger e() const = 0; - - /** - Returns the private P component of this RSA key - */ - virtual BigInteger p() const = 0; - - /** - Returns the private Q component of this RSA key - */ - virtual BigInteger q() const = 0; - - /** - Returns the private D component of this RSA key - */ - virtual BigInteger d() const = 0; + /** + Standard constructor + + \param p the provider associated with this context + */ + RSAContext(Provider *p) : PKeyBase(p, QStringLiteral("rsa")) {} + + /** + Generate an RSA private key + + If \a block is true, then this function blocks until completion. + Otherwise, this function returns immediately and finished() is + emitted when the operation completes. + + If an error occurs during generation, then the operation will + complete and isNull() will return true. + + \param bits the length of the key to generate, in bits + \param exp the exponent to use for generation + \param block whether to use blocking mode + */ + virtual void createPrivate(int bits, int exp, bool block) = 0; + + /** + Create an RSA private key based on the five components + + \param n the N parameter + \param e the public exponent + \param p the P parameter + \param q the Q parameter + \param d the D parameter + */ + virtual void createPrivate(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d) = 0; + + /** + Create an RSA public key based on the two public components + + \param n the N parameter + \param e the public exponent + */ + virtual void createPublic(const BigInteger &n, const BigInteger &e) = 0; + + /** + Returns the public N component of this RSA key + */ + virtual BigInteger n() const = 0; + + /** + Returns the public E component of this RSA key + */ + virtual BigInteger e() const = 0; + + /** + Returns the private P component of this RSA key + */ + virtual BigInteger p() const = 0; + + /** + Returns the private Q component of this RSA key + */ + virtual BigInteger q() const = 0; + + /** + Returns the private D component of this RSA key + */ + virtual BigInteger d() const = 0; }; /** @@ -717,61 +718,61 @@ */ class QCA_EXPORT DSAContext : public PKeyBase { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - */ - DSAContext(Provider *p) : PKeyBase(p, QStringLiteral("dsa")) {} - - /** - Generate a DSA private key - - If \a block is true, then this function blocks until completion. - Otherwise, this function returns immediately and finished() is - emitted when the operation completes. - - If an error occurs during generation, then the operation will - complete and isNull() will return true. - - \param domain the domain values to use for generation - \param block whether to use blocking mode - */ - virtual void createPrivate(const DLGroup &domain, bool block) = 0; - - /** - Create a DSA private key based on its numeric components - - \param domain the domain values to use for generation - \param y the public Y component - \param x the private X component - */ - virtual void createPrivate(const DLGroup &domain, const BigInteger &y, const BigInteger &x) = 0; - - /** - Create a DSA public key based on its numeric components - - \param domain the domain values to use for generation - \param y the public Y component - */ - virtual void createPublic(const DLGroup &domain, const BigInteger &y) = 0; - - /** - Returns the public domain component of this DSA key - */ - virtual DLGroup domain() const = 0; - - /** - Returns the public Y component of this DSA key - */ - virtual BigInteger y() const = 0; - - /** - Returns the private X component of this DSA key - */ - virtual BigInteger x() const = 0; + /** + Standard constructor + + \param p the provider associated with this context + */ + DSAContext(Provider *p) : PKeyBase(p, QStringLiteral("dsa")) {} + + /** + Generate a DSA private key + + If \a block is true, then this function blocks until completion. + Otherwise, this function returns immediately and finished() is + emitted when the operation completes. + + If an error occurs during generation, then the operation will + complete and isNull() will return true. + + \param domain the domain values to use for generation + \param block whether to use blocking mode + */ + virtual void createPrivate(const DLGroup &domain, bool block) = 0; + + /** + Create a DSA private key based on its numeric components + + \param domain the domain values to use for generation + \param y the public Y component + \param x the private X component + */ + virtual void createPrivate(const DLGroup &domain, const BigInteger &y, const BigInteger &x) = 0; + + /** + Create a DSA public key based on its numeric components + + \param domain the domain values to use for generation + \param y the public Y component + */ + virtual void createPublic(const DLGroup &domain, const BigInteger &y) = 0; + + /** + Returns the public domain component of this DSA key + */ + virtual DLGroup domain() const = 0; + + /** + Returns the public Y component of this DSA key + */ + virtual BigInteger y() const = 0; + + /** + Returns the private X component of this DSA key + */ + virtual BigInteger x() const = 0; }; /** @@ -787,63 +788,63 @@ */ class QCA_EXPORT DHContext : public PKeyBase { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - */ - DHContext(Provider *p) : PKeyBase(p, QStringLiteral("dh")) {} - - /** - Generate a Diffie-Hellman private key - - If \a block is true, then this function blocks until completion. - Otherwise, this function returns immediately and finished() is - emitted when the operation completes. - - If an error occurs during generation, then the operation will - complete and isNull() will return true. - - \param domain the domain values to use for generation - \param block whether to use blocking mode - */ - virtual void createPrivate(const DLGroup &domain, bool block) = 0; - - /** - Create a Diffie-Hellman private key based on its numeric - components - - \param domain the domain values to use for generation - \param y the public Y component - \param x the private X component - */ - virtual void createPrivate(const DLGroup &domain, const BigInteger &y, const BigInteger &x) = 0; - - /** - Create a Diffie-Hellman public key based on its numeric - components - - \param domain the domain values to use for generation - \param y the public Y component - */ - virtual void createPublic(const DLGroup &domain, const BigInteger &y) = 0; - - /** - Returns the public domain component of this Diffie-Hellman key - */ - virtual DLGroup domain() const = 0; - - /** - Returns the public Y component of this Diffie-Hellman key - */ - virtual BigInteger y() const = 0; - - /** - Returns the private X component of this Diffie-Hellman key - */ - virtual BigInteger x() const = 0; + /** + Standard constructor + + \param p the provider associated with this context + */ + DHContext(Provider *p) : PKeyBase(p, QStringLiteral("dh")) {} + + /** + Generate a Diffie-Hellman private key + + If \a block is true, then this function blocks until completion. + Otherwise, this function returns immediately and finished() is + emitted when the operation completes. + + If an error occurs during generation, then the operation will + complete and isNull() will return true. + + \param domain the domain values to use for generation + \param block whether to use blocking mode + */ + virtual void createPrivate(const DLGroup &domain, bool block) = 0; + + /** + Create a Diffie-Hellman private key based on its numeric + components + + \param domain the domain values to use for generation + \param y the public Y component + \param x the private X component + */ + virtual void createPrivate(const DLGroup &domain, const BigInteger &y, const BigInteger &x) = 0; + + /** + Create a Diffie-Hellman public key based on its numeric + components + + \param domain the domain values to use for generation + \param y the public Y component + */ + virtual void createPublic(const DLGroup &domain, const BigInteger &y) = 0; + + /** + Returns the public domain component of this Diffie-Hellman key + */ + virtual DLGroup domain() const = 0; + + /** + Returns the public Y component of this Diffie-Hellman key + */ + virtual BigInteger y() const = 0; + + /** + Returns the private X component of this Diffie-Hellman key + */ + virtual BigInteger x() const = 0; }; /** @@ -863,141 +864,141 @@ */ class QCA_EXPORT PKeyContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the provider associated with this context - */ - PKeyContext(Provider *p) : BasicContext(p, QStringLiteral("pkey")) {} + \param p the provider associated with this context + */ + PKeyContext(Provider *p) : BasicContext(p, QStringLiteral("pkey")) {} - /** - Returns a list of supported public key types - */ - virtual QList supportedTypes() const = 0; + /** + Returns a list of supported public key types + */ + virtual QList supportedTypes() const = 0; - /** - Returns a list of public key types that can be serialized and - deserialized into DER and PEM format - */ - virtual QList supportedIOTypes() const = 0; + /** + Returns a list of public key types that can be serialized and + deserialized into DER and PEM format + */ + virtual QList supportedIOTypes() const = 0; - /** - Returns a list of password-based encryption algorithms that are - supported for private key serialization and deserialization - */ - virtual QList supportedPBEAlgorithms() const = 0; + /** + Returns a list of password-based encryption algorithms that are + supported for private key serialization and deserialization + */ + virtual QList supportedPBEAlgorithms() const = 0; - /** - Returns the key held by this object, or 0 if there is no key - */ - virtual PKeyBase *key() = 0; + /** + Returns the key held by this object, or 0 if there is no key + */ + virtual PKeyBase *key() = 0; - /** - Returns the key held by this object, or 0 if there is no key - */ - virtual const PKeyBase *key() const = 0; + /** + Returns the key held by this object, or 0 if there is no key + */ + virtual const PKeyBase *key() const = 0; - /** - Sets the key for this object. If this object already had a key, - then the old one is destructed. This object takes ownership of - the key. + /** + Sets the key for this object. If this object already had a key, + then the old one is destructed. This object takes ownership of + the key. - \param key the key to be set for this object - */ - virtual void setKey(PKeyBase *key) = 0; + \param key the key to be set for this object + */ + virtual void setKey(PKeyBase *key) = 0; - /** - Attempt to import a key from another provider. Returns true if - successful, otherwise false. + /** + Attempt to import a key from another provider. Returns true if + successful, otherwise false. - Generally this function is used if the specified key's provider - does not support serialization, but your provider does. The call - to this function would then be followed by an export function, - such as publicToDER(). + Generally this function is used if the specified key's provider + does not support serialization, but your provider does. The call + to this function would then be followed by an export function, + such as publicToDER(). - \param key the key to be imported - */ - virtual bool importKey(const PKeyBase *key) = 0; + \param key the key to be imported + */ + virtual bool importKey(const PKeyBase *key) = 0; - /** - Convert a public key to DER format, and return the value + /** + Convert a public key to DER format, and return the value - Returns an empty array on error. - */ - virtual QByteArray publicToDER() const; + Returns an empty array on error. + */ + virtual QByteArray publicToDER() const; - /** - Convert a public key to PEM format, and return the value + /** + Convert a public key to PEM format, and return the value - Returns an empty string on error. - */ - virtual QString publicToPEM() const; + Returns an empty string on error. + */ + virtual QString publicToPEM() const; - /** - Read DER-formatted input and convert it into a public key + /** + Read DER-formatted input and convert it into a public key - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param a the input data - */ - virtual ConvertResult publicFromDER(const QByteArray &a); + \param a the input data + */ + virtual ConvertResult publicFromDER(const QByteArray &a); - /** - Read PEM-formatted input and convert it into a public key + /** + Read PEM-formatted input and convert it into a public key - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param s the input data - */ - virtual ConvertResult publicFromPEM(const QString &s); + \param s the input data + */ + virtual ConvertResult publicFromPEM(const QString &s); - /** - Convert a private key to DER format, and return the value + /** + Convert a private key to DER format, and return the value - Returns an empty array on error. + Returns an empty array on error. - \param passphrase the passphrase to encode the result with, or an - empty array if no encryption is desired - \param pbe the encryption algorithm to use, if applicable - */ - virtual SecureArray privateToDER(const SecureArray &passphrase, PBEAlgorithm pbe) const; + \param passphrase the passphrase to encode the result with, or an + empty array if no encryption is desired + \param pbe the encryption algorithm to use, if applicable + */ + virtual SecureArray privateToDER(const SecureArray &passphrase, PBEAlgorithm pbe) const; - /** - Convert a private key to PEM format, and return the value + /** + Convert a private key to PEM format, and return the value - Returns an empty string on error. + Returns an empty string on error. - \param passphrase the passphrase to encode the result with, or an - empty array if no encryption is desired - \param pbe the encryption algorithm to use, if applicable - */ - virtual QString privateToPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const; + \param passphrase the passphrase to encode the result with, or an + empty array if no encryption is desired + \param pbe the encryption algorithm to use, if applicable + */ + virtual QString privateToPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const; - /** - Read DER-formatted input and convert it into a private key + /** + Read DER-formatted input and convert it into a private key - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param a the input data - \param passphrase the passphrase needed to decrypt, if applicable - */ - virtual ConvertResult privateFromDER(const SecureArray &a, const SecureArray &passphrase); + \param a the input data + \param passphrase the passphrase needed to decrypt, if applicable + */ + virtual ConvertResult privateFromDER(const SecureArray &a, const SecureArray &passphrase); - /** - Read PEM-formatted input and convert it into a private key + /** + Read PEM-formatted input and convert it into a private key - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param s the input data - \param passphrase the passphrase needed to decrypt, if applicable - */ - virtual ConvertResult privateFromPEM(const QString &s, const SecureArray &passphrase); + \param s the input data + \param passphrase the passphrase needed to decrypt, if applicable + */ + virtual ConvertResult privateFromPEM(const QString &s, const SecureArray &passphrase); }; /** @@ -1013,49 +1014,49 @@ */ class QCA_EXPORT CertBase : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the provider associated with this context - \param type the type of certificate-like object provided by this context - */ - CertBase(Provider *p, const QString &type) : BasicContext(p, type) {} + \param p the provider associated with this context + \param type the type of certificate-like object provided by this context + */ + CertBase(Provider *p, const QString &type) : BasicContext(p, type) {} - /** - Convert this object to DER format, and return the value + /** + Convert this object to DER format, and return the value - Returns an empty array on error. - */ - virtual QByteArray toDER() const = 0; + Returns an empty array on error. + */ + virtual QByteArray toDER() const = 0; - /** - Convert this object to PEM format, and return the value + /** + Convert this object to PEM format, and return the value - Returns an empty string on error. - */ - virtual QString toPEM() const = 0; + Returns an empty string on error. + */ + virtual QString toPEM() const = 0; - /** - Read DER-formatted input and convert it into this object + /** + Read DER-formatted input and convert it into this object - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param a the input data - */ - virtual ConvertResult fromDER(const QByteArray &a) = 0; + \param a the input data + */ + virtual ConvertResult fromDER(const QByteArray &a) = 0; - /** - Read PEM-formatted input and convert it into this object + /** + Read PEM-formatted input and convert it into this object - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param s the input data - */ - virtual ConvertResult fromPEM(const QString &s) = 0; + \param s the input data + */ + virtual ConvertResult fromPEM(const QString &s) = 0; }; /** @@ -1075,132 +1076,132 @@ class QCA_EXPORT CertContextProps { public: - /** - The X.509 certificate version, usually 3 + /** + The X.509 certificate version, usually 3 - This field is for certificates only. - */ - int version; + This field is for certificates only. + */ + int version; - /** - The time the certificate becomes valid (often the time of create) + /** + The time the certificate becomes valid (often the time of create) - This field is for certificates only. - */ - QDateTime start; + This field is for certificates only. + */ + QDateTime start; - /** - The time the certificate expires + /** + The time the certificate expires - This field is for certificates only. - */ - QDateTime end; + This field is for certificates only. + */ + QDateTime end; - /** - The subject information - */ - CertificateInfoOrdered subject; + /** + The subject information + */ + CertificateInfoOrdered subject; - /** - The issuer information + /** + The issuer information - This field is for certificates only. - */ - CertificateInfoOrdered issuer; + This field is for certificates only. + */ + CertificateInfoOrdered issuer; - /** - The constraints - */ - Constraints constraints; + /** + The constraints + */ + Constraints constraints; - /** - The policies - */ - QStringList policies; + /** + The policies + */ + QStringList policies; - /** - A list of URIs for CRLs + /** + A list of URIs for CRLs - This field is for certificates only. - */ - QStringList crlLocations; + This field is for certificates only. + */ + QStringList crlLocations; - /** - A list of URIs for issuer certificates + /** + A list of URIs for issuer certificates - This field is for certificates only. - */ - QStringList issuerLocations; + This field is for certificates only. + */ + QStringList issuerLocations; - /** - A list of URIs for OCSP services + /** + A list of URIs for OCSP services - This field is for certificates only. - */ - QStringList ocspLocations; + This field is for certificates only. + */ + QStringList ocspLocations; - /** - The certificate serial number + /** + The certificate serial number - This field is for certificates only. - */ - BigInteger serial; + This field is for certificates only. + */ + BigInteger serial; - /** - True if the certificate is a CA or the certificate request is - requesting to be a CA, otherwise false - */ - bool isCA; + /** + True if the certificate is a CA or the certificate request is + requesting to be a CA, otherwise false + */ + bool isCA; - /** - True if the certificate is self-signed + /** + True if the certificate is self-signed - This field is for certificates only. - */ - bool isSelfSigned; + This field is for certificates only. + */ + bool isSelfSigned; - /** - The path limit - */ - int pathLimit; + /** + The path limit + */ + int pathLimit; - /** - The signature data - */ - QByteArray sig; + /** + The signature data + */ + QByteArray sig; - /** - The signature algorithm used to create the signature - */ - SignatureAlgorithm sigalgo; + /** + The signature algorithm used to create the signature + */ + SignatureAlgorithm sigalgo; - /** - The subject id + /** + The subject id - This field is for certificates only. - */ - QByteArray subjectId; + This field is for certificates only. + */ + QByteArray subjectId; - /** - The issuer id + /** + The issuer id - This field is for certificates only. - */ - QByteArray issuerId; + This field is for certificates only. + */ + QByteArray issuerId; - /** - The SPKAC challenge value + /** + The SPKAC challenge value - This field is for certificate requests only. - */ - QString challenge; + This field is for certificate requests only. + */ + QString challenge; - /** - The format used for the certificate request + /** + The format used for the certificate request - This field is for certificate requests only. - */ - CertificateRequestFormat format; + This field is for certificate requests only. + */ + CertificateRequestFormat format; }; /** @@ -1218,45 +1219,45 @@ class QCA_EXPORT CRLContextProps { public: - /** - The issuer information of the CRL - */ - CertificateInfoOrdered issuer; - - /** - The CRL number, which increases at each update - */ - int number; - - /** - The time this CRL was created - */ - QDateTime thisUpdate; - - /** - The time this CRL expires, and the next CRL should be fetched - */ - QDateTime nextUpdate; - - /** - The revoked entries - */ - QList revoked; - - /** - The signature data of the CRL - */ - QByteArray sig; - - /** - The signature algorithm used by the issuer to sign the CRL - */ - SignatureAlgorithm sigalgo; - - /** - The issuer id - */ - QByteArray issuerId; + /** + The issuer information of the CRL + */ + CertificateInfoOrdered issuer; + + /** + The CRL number, which increases at each update + */ + int number; + + /** + The time this CRL was created + */ + QDateTime thisUpdate; + + /** + The time this CRL expires, and the next CRL should be fetched + */ + QDateTime nextUpdate; + + /** + The revoked entries + */ + QList revoked; + + /** + The signature data of the CRL + */ + QByteArray sig; + + /** + The signature algorithm used by the issuer to sign the CRL + */ + SignatureAlgorithm sigalgo; + + /** + The issuer id + */ + QByteArray issuerId; }; class CRLContext; @@ -1273,84 +1274,84 @@ */ class QCA_EXPORT CertContext : public CertBase { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - */ - CertContext(Provider *p) : CertBase(p, QStringLiteral("cert")) {} - - /** - Create a self-signed certificate based on the given options and - private key. Returns true if successful, otherwise false. - - If successful, this object becomes the self-signed certificate. - If unsuccessful, this object is considered to be in an - uninitialized state. - - \param opts the options to set on the certificate - \param priv the key to be used to sign the certificate - */ - virtual bool createSelfSigned(const CertificateOptions &opts, const PKeyContext &priv) = 0; - - /** - Returns a pointer to the properties of this certificate - */ - virtual const CertContextProps *props() const = 0; - - /** - Returns true if this certificate is equal to another certificate, - otherwise false - - \param other the certificate to compare with - */ - virtual bool compare(const CertContext *other) const = 0; - - /** - Returns a copy of this certificate's public key. The caller is - responsible for deleting it. - */ - virtual PKeyContext *subjectPublicKey() const = 0; - - /** - Returns true if this certificate is an issuer of another - certificate, otherwise false - - \param other the issued certificate to check - */ - virtual bool isIssuerOf(const CertContext *other) const = 0; - - /** - Validate this certificate - - This function is blocking. - - \param trusted list of trusted certificates - \param untrusted list of untrusted certificates (can be empty) - \param crls list of CRLs (can be empty) - \param u the desired usage for this certificate - \param vf validation options - */ - virtual Validity validate(const QList &trusted, const QList &untrusted, const QList &crls, UsageMode u, ValidateFlags vf) const = 0; - - /** - Validate a certificate chain. This function makes no use of the - certificate represented by this object, and it can be used even - if this object is in an uninitialized state. - - This function is blocking. - - \param chain list of certificates in the chain, starting with the - user certificate. It is not necessary for the chain to contain - the final root certificate. - \param trusted list of trusted certificates - \param crls list of CRLs (can be empty) - \param u the desired usage for the user certificate in the chain - \param vf validation options - */ - virtual Validity validate_chain(const QList &chain, const QList &trusted, const QList &crls, UsageMode u, ValidateFlags vf) const = 0; + /** + Standard constructor + + \param p the provider associated with this context + */ + CertContext(Provider *p) : CertBase(p, QStringLiteral("cert")) {} + + /** + Create a self-signed certificate based on the given options and + private key. Returns true if successful, otherwise false. + + If successful, this object becomes the self-signed certificate. + If unsuccessful, this object is considered to be in an + uninitialized state. + + \param opts the options to set on the certificate + \param priv the key to be used to sign the certificate + */ + virtual bool createSelfSigned(const CertificateOptions &opts, const PKeyContext &priv) = 0; + + /** + Returns a pointer to the properties of this certificate + */ + virtual const CertContextProps *props() const = 0; + + /** + Returns true if this certificate is equal to another certificate, + otherwise false + + \param other the certificate to compare with + */ + virtual bool compare(const CertContext *other) const = 0; + + /** + Returns a copy of this certificate's public key. The caller is + responsible for deleting it. + */ + virtual PKeyContext *subjectPublicKey() const = 0; + + /** + Returns true if this certificate is an issuer of another + certificate, otherwise false + + \param other the issued certificate to check + */ + virtual bool isIssuerOf(const CertContext *other) const = 0; + + /** + Validate this certificate + + This function is blocking. + + \param trusted list of trusted certificates + \param untrusted list of untrusted certificates (can be empty) + \param crls list of CRLs (can be empty) + \param u the desired usage for this certificate + \param vf validation options + */ + virtual Validity validate(const QList &trusted, const QList &untrusted, const QList &crls, UsageMode u, ValidateFlags vf) const = 0; + + /** + Validate a certificate chain. This function makes no use of the + certificate represented by this object, and it can be used even + if this object is in an uninitialized state. + + This function is blocking. + + \param chain list of certificates in the chain, starting with the + user certificate. It is not necessary for the chain to contain + the final root certificate. + \param trusted list of trusted certificates + \param crls list of CRLs (can be empty) + \param u the desired usage for the user certificate in the chain + \param vf validation options + */ + virtual Validity validate_chain(const QList &chain, const QList &trusted, const QList &crls, UsageMode u, ValidateFlags vf) const = 0; }; /** @@ -1366,73 +1367,73 @@ */ class QCA_EXPORT CSRContext : public CertBase { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the provider associated with this context - */ - CSRContext(Provider *p) : CertBase(p, QStringLiteral("csr")) {} - - /** - Returns true if the provider of this object supports the specified - format, otherwise false - - \param f the format to test for support for. - */ - virtual bool canUseFormat(CertificateRequestFormat f) const = 0; - - /** - Create a certificate request based on the given options and - private key. Returns true if successful, otherwise false. - - If successful, this object becomes the certificate request. - If unsuccessful, this object is considered to be in an - uninitialized state. - - \param opts the options to set on the certificate - \param priv the key to be used to sign the certificate - */ - virtual bool createRequest(const CertificateOptions &opts, const PKeyContext &priv) = 0; - - /** - Returns a pointer to the properties of this certificate request - */ - virtual const CertContextProps *props() const = 0; - - /** - Returns true if this certificate request is equal to another - certificate request, otherwise false - - \param other the certificate request to compare with - */ - virtual bool compare(const CSRContext *other) const = 0; - - /** - Returns a copy of this certificate request's public key. The - caller is responsible for deleting it. - */ - virtual PKeyContext *subjectPublicKey() const = 0; - - /** - Convert this certificate request to Netscape SPKAC format, and - return the value - - Returns an empty string on error. - */ - virtual QString toSPKAC() const = 0; - - /** - Read Netscape SPKAC input and convert it into a certificate - request - - Returns QCA::ConvertGood if successful, otherwise some error - value. - - \param s the input data - */ - virtual ConvertResult fromSPKAC(const QString &s) = 0; + /** + Standard constructor + + \param p the provider associated with this context + */ + CSRContext(Provider *p) : CertBase(p, QStringLiteral("csr")) {} + + /** + Returns true if the provider of this object supports the specified + format, otherwise false + + \param f the format to test for support for. + */ + virtual bool canUseFormat(CertificateRequestFormat f) const = 0; + + /** + Create a certificate request based on the given options and + private key. Returns true if successful, otherwise false. + + If successful, this object becomes the certificate request. + If unsuccessful, this object is considered to be in an + uninitialized state. + + \param opts the options to set on the certificate + \param priv the key to be used to sign the certificate + */ + virtual bool createRequest(const CertificateOptions &opts, const PKeyContext &priv) = 0; + + /** + Returns a pointer to the properties of this certificate request + */ + virtual const CertContextProps *props() const = 0; + + /** + Returns true if this certificate request is equal to another + certificate request, otherwise false + + \param other the certificate request to compare with + */ + virtual bool compare(const CSRContext *other) const = 0; + + /** + Returns a copy of this certificate request's public key. The + caller is responsible for deleting it. + */ + virtual PKeyContext *subjectPublicKey() const = 0; + + /** + Convert this certificate request to Netscape SPKAC format, and + return the value + + Returns an empty string on error. + */ + virtual QString toSPKAC() const = 0; + + /** + Read Netscape SPKAC input and convert it into a certificate + request + + Returns QCA::ConvertGood if successful, otherwise some error + value. + + \param s the input data + */ + virtual ConvertResult fromSPKAC(const QString &s) = 0; }; /** @@ -1447,26 +1448,26 @@ */ class QCA_EXPORT CRLContext : public CertBase { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the provider associated with this context - */ - CRLContext(Provider *p) : CertBase(p, QStringLiteral("crl")) {} + \param p the provider associated with this context + */ + CRLContext(Provider *p) : CertBase(p, QStringLiteral("crl")) {} - /** - Returns a pointer to the properties of this CRL - */ - virtual const CRLContextProps *props() const = 0; + /** + Returns a pointer to the properties of this CRL + */ + virtual const CRLContextProps *props() const = 0; - /** - Returns true if this CRL is equal to another CRL, otherwise false + /** + Returns true if this CRL is equal to another CRL, otherwise false - \param other the CRL to compare with - */ - virtual bool compare(const CRLContext *other) const = 0; + \param other the CRL to compare with + */ + virtual bool compare(const CRLContext *other) const = 0; }; /** @@ -1482,39 +1483,39 @@ */ class QCA_EXPORT CertCollectionContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the provider associated with this context - */ - CertCollectionContext(Provider *p) : BasicContext(p, QStringLiteral("certcollection")) {} + \param p the provider associated with this context + */ + CertCollectionContext(Provider *p) : BasicContext(p, QStringLiteral("certcollection")) {} - /** - Create PKCS#7 DER output based on the input certificates and CRLs + /** + Create PKCS#7 DER output based on the input certificates and CRLs - Returns an empty array on error. + Returns an empty array on error. - \param certs list of certificates to store in the output - \param crls list of CRLs to store in the output - */ - virtual QByteArray toPKCS7(const QList &certs, const QList &crls) const = 0; + \param certs list of certificates to store in the output + \param crls list of CRLs to store in the output + */ + virtual QByteArray toPKCS7(const QList &certs, const QList &crls) const = 0; - /** - Read PKCS#7 DER input and convert it into a list of certificates - and CRLs + /** + Read PKCS#7 DER input and convert it into a list of certificates + and CRLs - The caller is responsible for deleting the returned items. + The caller is responsible for deleting the returned items. - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param a the input data - \param certs the destination list for the certificates - \param crls the destination list for the CRLs - */ - virtual ConvertResult fromPKCS7(const QByteArray &a, QList *certs, QList *crls) const = 0; + \param a the input data + \param certs the destination list for the certificates + \param crls the destination list for the CRLs + */ + virtual ConvertResult fromPKCS7(const QByteArray &a, QList *certs, QList *crls) const = 0; }; /** @@ -1530,69 +1531,69 @@ */ class QCA_EXPORT CAContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the Provider associated with this context - */ - CAContext(Provider *p) : BasicContext(p, QStringLiteral("ca")) {} - - /** - Prepare the object for usage - - This must be called before any CA operations are performed. - - \param cert the certificate of the CA - \param priv the private key of the CA - */ - virtual void setup(const CertContext &cert, const PKeyContext &priv) = 0; - - /** - Returns a copy of the CA's certificate. The caller is responsible - for deleting it. - */ - virtual CertContext *certificate() const = 0; - - /** - Issue a certificate based on a certificate request, and return - the certificate. The caller is responsible for deleting it. - - \param req the certificate request - \param notValidAfter the expiration date - */ - virtual CertContext *signRequest(const CSRContext &req, const QDateTime ¬ValidAfter) const = 0; - - /** - Issue a certificate based on a public key and options, and return - the certificate. The caller is responsible for deleting it. - - \param pub the public key of the certificate - \param opts the options to use for generation - */ - virtual CertContext *createCertificate(const PKeyContext &pub, const CertificateOptions &opts) const = 0; - - /** - Create a new CRL and return it. The caller is responsible for - deleting it. - - The CRL has no entries in it. - - \param nextUpdate the expiration date of the CRL - */ - virtual CRLContext *createCRL(const QDateTime &nextUpdate) const = 0; - - /** - Update an existing CRL, by examining an old one and creating a new - one based on it. The new CRL is returned, and the caller is - responsible for deleting it. - - \param crl an existing CRL issued by this CA - \param entries the list of revoked entries - \param nextUpdate the expiration date of the new CRL - */ - virtual CRLContext *updateCRL(const CRLContext &crl, const QList &entries, const QDateTime &nextUpdate) const = 0; + /** + Standard constructor + + \param p the Provider associated with this context + */ + CAContext(Provider *p) : BasicContext(p, QStringLiteral("ca")) {} + + /** + Prepare the object for usage + + This must be called before any CA operations are performed. + + \param cert the certificate of the CA + \param priv the private key of the CA + */ + virtual void setup(const CertContext &cert, const PKeyContext &priv) = 0; + + /** + Returns a copy of the CA's certificate. The caller is responsible + for deleting it. + */ + virtual CertContext *certificate() const = 0; + + /** + Issue a certificate based on a certificate request, and return + the certificate. The caller is responsible for deleting it. + + \param req the certificate request + \param notValidAfter the expiration date + */ + virtual CertContext *signRequest(const CSRContext &req, const QDateTime ¬ValidAfter) const = 0; + + /** + Issue a certificate based on a public key and options, and return + the certificate. The caller is responsible for deleting it. + + \param pub the public key of the certificate + \param opts the options to use for generation + */ + virtual CertContext *createCertificate(const PKeyContext &pub, const CertificateOptions &opts) const = 0; + + /** + Create a new CRL and return it. The caller is responsible for + deleting it. + + The CRL has no entries in it. + + \param nextUpdate the expiration date of the CRL + */ + virtual CRLContext *createCRL(const QDateTime &nextUpdate) const = 0; + + /** + Update an existing CRL, by examining an old one and creating a new + one based on it. The new CRL is returned, and the caller is + responsible for deleting it. + + \param crl an existing CRL issued by this CA + \param entries the list of revoked entries + \param nextUpdate the expiration date of the new CRL + */ + virtual CRLContext *updateCRL(const CRLContext &crl, const QList &entries, const QDateTime &nextUpdate) const = 0; }; /** @@ -1607,42 +1608,42 @@ */ class QCA_EXPORT PKCS12Context : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the Provider associated with this context - */ - PKCS12Context(Provider *p) : BasicContext(p, QStringLiteral("pkcs12")) {} + \param p the Provider associated with this context + */ + PKCS12Context(Provider *p) : BasicContext(p, QStringLiteral("pkcs12")) {} - /** - Create PKCS#12 DER output based on a set of input items + /** + Create PKCS#12 DER output based on a set of input items - Returns an empty array on error. + Returns an empty array on error. - \param name the friendly name of the data - \param chain the certificate chain to store - \param priv the private key to store - \param passphrase the passphrase to encrypt the PKCS#12 data with - */ - virtual QByteArray toPKCS12(const QString &name, const QList &chain, const PKeyContext &priv, const SecureArray &passphrase) const = 0; + \param name the friendly name of the data + \param chain the certificate chain to store + \param priv the private key to store + \param passphrase the passphrase to encrypt the PKCS#12 data with + */ + virtual QByteArray toPKCS12(const QString &name, const QList &chain, const PKeyContext &priv, const SecureArray &passphrase) const = 0; - /** - Read PKCS#12 DER input and convert it into a set of output items + /** + Read PKCS#12 DER input and convert it into a set of output items - The caller is responsible for deleting the returned items. + The caller is responsible for deleting the returned items. - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param in the input data - \param passphrase the passphrase needed to decrypt the input data - \param name the destination string for the friendly name - \param chain the destination list for the certificate chain - \param priv address of a pointer to accept the private key - */ - virtual ConvertResult fromPKCS12(const QByteArray &in, const SecureArray &passphrase, QString *name, QList *chain, PKeyContext **priv) const = 0; + \param in the input data + \param passphrase the passphrase needed to decrypt the input data + \param name the destination string for the friendly name + \param chain the destination list for the certificate chain + \param priv address of a pointer to accept the private key + */ + virtual ConvertResult fromPKCS12(const QByteArray &in, const SecureArray &passphrase, QString *name, QList *chain, PKeyContext **priv) const = 0; }; /** @@ -1660,50 +1661,50 @@ class QCA_EXPORT PGPKeyContextProps { public: - /** - The key id - */ - QString keyId; - - /** - List of user id strings for the key, the first one being the - primary user id - */ - QStringList userIds; - - /** - True if this key is a secret key, otherwise false - */ - bool isSecret; - - /** - The time the key was created - */ - QDateTime creationDate; - - /** - The time the key expires - */ - QDateTime expirationDate; - - /** - The hex fingerprint of the key - - The format is all lowercase with no spaces. - */ - QString fingerprint; - - /** - True if this key is in a keyring (and thus usable), otherwise - false - */ - bool inKeyring; - - /** - True if this key is trusted (e.g. signed by the keyring owner or - via some web-of-trust), otherwise false - */ - bool isTrusted; + /** + The key id + */ + QString keyId; + + /** + List of user id strings for the key, the first one being the + primary user id + */ + QStringList userIds; + + /** + True if this key is a secret key, otherwise false + */ + bool isSecret; + + /** + The time the key was created + */ + QDateTime creationDate; + + /** + The time the key expires + */ + QDateTime expirationDate; + + /** + The hex fingerprint of the key + + The format is all lowercase with no spaces. + */ + QString fingerprint; + + /** + True if this key is in a keyring (and thus usable), otherwise + false + */ + bool inKeyring; + + /** + True if this key is trusted (e.g. signed by the keyring owner or + via some web-of-trust), otherwise false + */ + bool isTrusted; }; /** @@ -1718,49 +1719,49 @@ */ class QCA_EXPORT PGPKeyContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the Provider associated with this context - */ - PGPKeyContext(Provider *p) : BasicContext(p, QStringLiteral("pgpkey")) {} + \param p the Provider associated with this context + */ + PGPKeyContext(Provider *p) : BasicContext(p, QStringLiteral("pgpkey")) {} - /** - Returns a pointer to the properties of this key - */ - virtual const PGPKeyContextProps *props() const = 0; + /** + Returns a pointer to the properties of this key + */ + virtual const PGPKeyContextProps *props() const = 0; - /** - Convert the key to binary format, and return the value - */ - virtual QByteArray toBinary() const = 0; + /** + Convert the key to binary format, and return the value + */ + virtual QByteArray toBinary() const = 0; - /** - Convert the key to ascii-armored format, and return the value - */ - virtual QString toAscii() const = 0; + /** + Convert the key to ascii-armored format, and return the value + */ + virtual QString toAscii() const = 0; - /** - Read binary input and convert it into a key + /** + Read binary input and convert it into a key - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param a the input data - */ - virtual ConvertResult fromBinary(const QByteArray &a) = 0; + \param a the input data + */ + virtual ConvertResult fromBinary(const QByteArray &a) = 0; - /** - Read ascii-armored input and convert it into a key + /** + Read ascii-armored input and convert it into a key - Returns QCA::ConvertGood if successful, otherwise some error - value. + Returns QCA::ConvertGood if successful, otherwise some error + value. - \param s the input data - */ - virtual ConvertResult fromAscii(const QString &s) = 0; + \param s the input data + */ + virtual ConvertResult fromAscii(const QString &s) = 0; }; /** @@ -1776,97 +1777,97 @@ */ class QCA_EXPORT KeyStoreEntryContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor - - \param p the Provider associated with this context - */ - KeyStoreEntryContext(Provider *p) : BasicContext(p, QStringLiteral("keystoreentry")) {} - - /** - Returns the entry type - */ - virtual KeyStoreEntry::Type type() const = 0; - - /** - Returns the entry id - - This id must be unique among all other entries in the same store. - */ - virtual QString id() const = 0; - - /** - Returns the name of this entry - */ - virtual QString name() const = 0; - - /** - Returns the id of the store that contains this entry - */ - virtual QString storeId() const = 0; - - /** - Returns the name of the store that contains this entry - */ - virtual QString storeName() const = 0; - - /** - Returns true if the private key of this entry is present for use - */ - virtual bool isAvailable() const; - - /** - Serialize the information about this entry - - This allows the entry object to be restored later, even if the - store that contains it is not present. - - \sa KeyStoreListContext::entryPassive() - */ - virtual QString serialize() const = 0; - - /** - If this entry is of type KeyStoreEntry::TypeKeyBundle, this - function returns the KeyBundle of the entry - */ - virtual KeyBundle keyBundle() const; - - /** - If this entry is of type KeyStoreEntry::TypeCertificate, this - function returns the Certificate of the entry - */ - virtual Certificate certificate() const; - - /** - If this entry is of type KeyStoreEntry::TypeCRL, this function - returns the CRL of the entry - */ - virtual CRL crl() const; - - /** - If this entry is of type KeyStoreEntry::TypePGPSecretKey, this - function returns the secret PGPKey of the entry - */ - virtual PGPKey pgpSecretKey() const; - - /** - If this entry is of type KeyStoreEntry::TypePGPPublicKey or - KeyStoreEntry::TypePGPSecretKey, this function returns the public - PGPKey of the entry - */ - virtual PGPKey pgpPublicKey() const; - - /** - Attempt to ensure the private key of this entry is usable and - accessible, potentially prompting the user and/or performing a - login to a token device. Returns true if the entry is now - accessible, or false if the entry cannot be made accessible. - - This function is blocking. - */ - virtual bool ensureAccess(); + /** + Standard constructor + + \param p the Provider associated with this context + */ + KeyStoreEntryContext(Provider *p) : BasicContext(p, QStringLiteral("keystoreentry")) {} + + /** + Returns the entry type + */ + virtual KeyStoreEntry::Type type() const = 0; + + /** + Returns the entry id + + This id must be unique among all other entries in the same store. + */ + virtual QString id() const = 0; + + /** + Returns the name of this entry + */ + virtual QString name() const = 0; + + /** + Returns the id of the store that contains this entry + */ + virtual QString storeId() const = 0; + + /** + Returns the name of the store that contains this entry + */ + virtual QString storeName() const = 0; + + /** + Returns true if the private key of this entry is present for use + */ + virtual bool isAvailable() const; + + /** + Serialize the information about this entry + + This allows the entry object to be restored later, even if the + store that contains it is not present. + + \sa KeyStoreListContext::entryPassive() + */ + virtual QString serialize() const = 0; + + /** + If this entry is of type KeyStoreEntry::TypeKeyBundle, this + function returns the KeyBundle of the entry + */ + virtual KeyBundle keyBundle() const; + + /** + If this entry is of type KeyStoreEntry::TypeCertificate, this + function returns the Certificate of the entry + */ + virtual Certificate certificate() const; + + /** + If this entry is of type KeyStoreEntry::TypeCRL, this function + returns the CRL of the entry + */ + virtual CRL crl() const; + + /** + If this entry is of type KeyStoreEntry::TypePGPSecretKey, this + function returns the secret PGPKey of the entry + */ + virtual PGPKey pgpSecretKey() const; + + /** + If this entry is of type KeyStoreEntry::TypePGPPublicKey or + KeyStoreEntry::TypePGPSecretKey, this function returns the public + PGPKey of the entry + */ + virtual PGPKey pgpPublicKey() const; + + /** + Attempt to ensure the private key of this entry is usable and + accessible, potentially prompting the user and/or performing a + login to a token device. Returns true if the entry is now + accessible, or false if the entry cannot be made accessible. + + This function is blocking. + */ + virtual bool ensureAccess(); }; /** @@ -1881,230 +1882,230 @@ */ class QCA_EXPORT KeyStoreListContext : public Provider::Context { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the Provider associated with this context - */ - KeyStoreListContext(Provider *p) : Provider::Context(p, QStringLiteral("keystorelist")) {} + \param p the Provider associated with this context + */ + KeyStoreListContext(Provider *p) : Provider::Context(p, QStringLiteral("keystorelist")) {} - /** - Starts the keystore provider - */ - virtual void start(); + /** + Starts the keystore provider + */ + virtual void start(); - /** - Enables or disables update events + /** + Enables or disables update events - The updated() and storeUpdated() signals might not be emitted if - updates are not enabled. + The updated() and storeUpdated() signals might not be emitted if + updates are not enabled. - \param enabled whether update notifications are enabled (true) or disabled (false) - */ - virtual void setUpdatesEnabled(bool enabled); + \param enabled whether update notifications are enabled (true) or disabled (false) + */ + virtual void setUpdatesEnabled(bool enabled); - /** - Returns a list of integer context ids, each representing a - keystore instance + /** + Returns a list of integer context ids, each representing a + keystore instance - If a keystore becomes unavailable and then later becomes - available again (for example, if a smart card is removed and - then the same one is inserted again), the integer context id - must be different than last time. - */ - virtual QList keyStores() = 0; + If a keystore becomes unavailable and then later becomes + available again (for example, if a smart card is removed and + then the same one is inserted again), the integer context id + must be different than last time. + */ + virtual QList keyStores() = 0; - /** - Returns the type of the specified store, or -1 if the integer - context id is invalid + /** + Returns the type of the specified store, or -1 if the integer + context id is invalid - \param id the id for the store context - */ - virtual KeyStore::Type type(int id) const = 0; + \param id the id for the store context + */ + virtual KeyStore::Type type(int id) const = 0; - /** - Returns the string id of the store, or an empty string if the - integer context id is invalid + /** + Returns the string id of the store, or an empty string if the + integer context id is invalid - The string id of the store should be unique to a single store, and - it should persist between availability/unavailability. For - example, a smart card that is removed and inserted again should - have the same string id (despite having a new integer context id). + The string id of the store should be unique to a single store, and + it should persist between availability/unavailability. For + example, a smart card that is removed and inserted again should + have the same string id (despite having a new integer context id). - \param id the id for the store context - */ - virtual QString storeId(int id) const = 0; + \param id the id for the store context + */ + virtual QString storeId(int id) const = 0; - /** - Returns the friendly name of the store, or an empty string if the - integer context id is invalid + /** + Returns the friendly name of the store, or an empty string if the + integer context id is invalid - \param id the id for the store context - */ - virtual QString name(int id) const = 0; + \param id the id for the store context + */ + virtual QString name(int id) const = 0; - /** - Returns true if the store is read-only + /** + Returns true if the store is read-only - If the integer context id is invalid, this function should return - true. + If the integer context id is invalid, this function should return + true. - \param id the id for the store context - */ - virtual bool isReadOnly(int id) const; + \param id the id for the store context + */ + virtual bool isReadOnly(int id) const; - /** - Returns the types supported by the store, or an empty list if the - integer context id is invalid + /** + Returns the types supported by the store, or an empty list if the + integer context id is invalid - This function should return all supported types, even if the store - doesn't actually contain entries for all of the types. + This function should return all supported types, even if the store + doesn't actually contain entries for all of the types. - \param id the id for the store context - */ - virtual QList entryTypes(int id) const = 0; + \param id the id for the store context + */ + virtual QList entryTypes(int id) const = 0; - /** - Returns the entries of the store, or an empty list if the integer - context id is invalid + /** + Returns the entries of the store, or an empty list if the integer + context id is invalid - The caller is responsible for deleting the returned entry objects. + The caller is responsible for deleting the returned entry objects. - \param id the id for the store context - */ - virtual QList entryList(int id) = 0; + \param id the id for the store context + */ + virtual QList entryList(int id) = 0; - /** - Returns a single entry in the store, if the entry id is already - known. If the entry does not exist, the function returns 0. + /** + Returns a single entry in the store, if the entry id is already + known. If the entry does not exist, the function returns 0. - The caller is responsible for deleting the returned entry object. + The caller is responsible for deleting the returned entry object. - \param id the id for the store context - \param entryId the entry to retrieve - */ - virtual KeyStoreEntryContext *entry(int id, const QString &entryId); + \param id the id for the store context + \param entryId the entry to retrieve + */ + virtual KeyStoreEntryContext *entry(int id, const QString &entryId); - /** - Returns a single entry, created from the serialization string of - a previous entry (using KeyStoreEntryContext::serialize()). If - the serialization string cannot be parsed by this provider, or the - entry cannot otherwise be created, the function returns 0. + /** + Returns a single entry, created from the serialization string of + a previous entry (using KeyStoreEntryContext::serialize()). If + the serialization string cannot be parsed by this provider, or the + entry cannot otherwise be created, the function returns 0. - The caller is responsible for deleting the returned entry object. + The caller is responsible for deleting the returned entry object. - This function must be thread-safe. + This function must be thread-safe. - \param serialized the serialized data to create the entry from - */ - virtual KeyStoreEntryContext *entryPassive(const QString &serialized); + \param serialized the serialized data to create the entry from + */ + virtual KeyStoreEntryContext *entryPassive(const QString &serialized); - /** - Write a KeyBundle to the store + /** + Write a KeyBundle to the store - Returns the entry id of the new item, or an empty string if there - was an error writing the item. + Returns the entry id of the new item, or an empty string if there + was an error writing the item. - \param id the id for the store context - \param kb the key bundle to add to the store - */ - virtual QString writeEntry(int id, const KeyBundle &kb); + \param id the id for the store context + \param kb the key bundle to add to the store + */ + virtual QString writeEntry(int id, const KeyBundle &kb); - /** - Write a Certificate to the store + /** + Write a Certificate to the store - Returns the entry id of the new item, or an empty string if there - was an error writing the item. + Returns the entry id of the new item, or an empty string if there + was an error writing the item. - \param id the id for the store context - \param cert the certificate to add to the store - */ - virtual QString writeEntry(int id, const Certificate &cert); + \param id the id for the store context + \param cert the certificate to add to the store + */ + virtual QString writeEntry(int id, const Certificate &cert); - /** - Write a CRL to the store + /** + Write a CRL to the store - Returns the entry id of the new item, or an empty string if there - was an error writing the item. + Returns the entry id of the new item, or an empty string if there + was an error writing the item. - \param id the id for the store context - \param crl the revocation list to add to the store - */ - virtual QString writeEntry(int id, const CRL &crl); + \param id the id for the store context + \param crl the revocation list to add to the store + */ + virtual QString writeEntry(int id, const CRL &crl); - /** - Write a PGPKey to the store + /** + Write a PGPKey to the store - Returns the entry id of the new item, or an empty string if there - was an error writing the item. + Returns the entry id of the new item, or an empty string if there + was an error writing the item. - \param id the id for the store context - \param key the PGP key to add to the store - */ - virtual QString writeEntry(int id, const PGPKey &key); + \param id the id for the store context + \param key the PGP key to add to the store + */ + virtual QString writeEntry(int id, const PGPKey &key); - /** - Remove an entry from the store + /** + Remove an entry from the store - Returns true if the entry is successfully removed, otherwise - false. + Returns true if the entry is successfully removed, otherwise + false. - \param id the id for the store context - \param entryId the entry to remove from the store - */ - virtual bool removeEntry(int id, const QString &entryId); + \param id the id for the store context + \param entryId the entry to remove from the store + */ + virtual bool removeEntry(int id, const QString &entryId); Q_SIGNALS: - /** - Emit this when the provider is busy looking for keystores. The - provider goes into a busy state when it has reason to believe - there are keystores present, but it still needs to check or query - some devices to see for sure. - - For example, if a smart card is inserted, then the provider may - immediately go into a busy state upon detecting the insert. - However, it may take some seconds before the smart card - information can be queried and reported by the provider. Once - the card is queried successfully, the provider would leave the - busy state and report the new keystore. - - When this object is first started with start(), it is assumed to - be in the busy state, so there is no need to emit this signal at - the beginning. - */ - void busyStart(); - - /** - Emit this to leave the busy state - - When this object is first started with start(), it is assumed to - be in the busy state. You must emit busyEnd() at some point, or - QCA will never ask you about keystores. - */ - void busyEnd(); - - /** - Indicates the list of keystores has changed, and that QCA should - call keyStores() to obtain the latest list - */ - void updated(); - - /** - Emitted when there is diagnostic text to report - - \param str the diagnostic text - */ - void diagnosticText(const QString &str); - - /** - Indicates that the entry list of a keystore has changed (entries - added, removed, or modified) - - \param id the id of the key store that has changed - */ - void storeUpdated(int id); + /** + Emit this when the provider is busy looking for keystores. The + provider goes into a busy state when it has reason to believe + there are keystores present, but it still needs to check or query + some devices to see for sure. + + For example, if a smart card is inserted, then the provider may + immediately go into a busy state upon detecting the insert. + However, it may take some seconds before the smart card + information can be queried and reported by the provider. Once + the card is queried successfully, the provider would leave the + busy state and report the new keystore. + + When this object is first started with start(), it is assumed to + be in the busy state, so there is no need to emit this signal at + the beginning. + */ + void busyStart(); + + /** + Emit this to leave the busy state + + When this object is first started with start(), it is assumed to + be in the busy state. You must emit busyEnd() at some point, or + QCA will never ask you about keystores. + */ + void busyEnd(); + + /** + Indicates the list of keystores has changed, and that QCA should + call keyStores() to obtain the latest list + */ + void updated(); + + /** + Emitted when there is diagnostic text to report + + \param str the diagnostic text + */ + void diagnosticText(const QString &str); + + /** + Indicates that the entry list of a keystore has changed (entries + added, removed, or modified) + + \param id the id of the key store that has changed + */ + void storeUpdated(int id); }; /** @@ -2119,14 +2120,14 @@ */ class QCA_EXPORT TLSSessionContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the Provider associated with this context - */ - TLSSessionContext(Provider *p) : BasicContext(p, QStringLiteral("tlssession")) {} + \param p the Provider associated with this context + */ + TLSSessionContext(Provider *p) : BasicContext(p, QStringLiteral("tlssession")) {} }; /** @@ -2141,351 +2142,350 @@ */ class QCA_EXPORT TLSContext : public Provider::Context { - Q_OBJECT + Q_OBJECT public: - /** - \class QCA::TLSContext::SessionInfo qcaprovider.h QtCrypto - - Information about an active TLS connection - - For efficiency and simplicity, the members are directly accessed. - - \ingroup ProviderAPI - */ - class SessionInfo - { - public: - /** - True if the TLS connection is compressed, otherwise false - */ - bool isCompressed; - - /** - The TLS protocol version being used for this connection - */ - TLS::Version version; - - /** - The cipher suite being used for this connection - - \sa TLSContext::supportedCipherSuites() - */ - QString cipherSuite; - - /** - The bit size of the cipher used for this connection - */ - int cipherBits; - - /** - The maximum bit size possible of the cipher used for this - connection - */ - int cipherMaxBits; - - /** - Pointer to the id of this TLS session, for use with - resuming - */ - TLSSessionContext *id; - }; + /** + \class QCA::TLSContext::SessionInfo qcaprovider.h QtCrypto + + Information about an active TLS connection + + For efficiency and simplicity, the members are directly accessed. + + \ingroup ProviderAPI + */ + class SessionInfo + { + public: + /** + True if the TLS connection is compressed, otherwise false + */ + bool isCompressed; + + /** + The TLS protocol version being used for this connection + */ + TLS::Version version; + + /** + The cipher suite being used for this connection + + \sa TLSContext::supportedCipherSuites() + */ + QString cipherSuite; + + /** + The bit size of the cipher used for this connection + */ + int cipherBits; + + /** + The maximum bit size possible of the cipher used for this + connection + */ + int cipherMaxBits; + + /** + Pointer to the id of this TLS session, for use with + resuming + */ + TLSSessionContext *id; + }; - /** - Result of a TLS operation - */ - enum Result - { - Success, ///< Operation completed - Error, ///< Operation failed - Continue ///< More data needed to complete operation - }; + /** + Result of a TLS operation + */ + enum Result { + Success, ///< Operation completed + Error, ///< Operation failed + Continue ///< More data needed to complete operation + }; - /** - Standard constructor + /** + Standard constructor - \param p the Provider associated with this context - \param type the name of the type of feature that supported by this context - */ - TLSContext(Provider *p, const QString &type) : Provider::Context(p, type) {} + \param p the Provider associated with this context + \param type the name of the type of feature that supported by this context + */ + TLSContext(Provider *p, const QString &type) : Provider::Context(p, type) {} - /** - Reset the object to its initial state - */ - virtual void reset() = 0; + /** + Reset the object to its initial state + */ + virtual void reset() = 0; - /** - Returns a list of supported cipher suites for the specified - SSL/TLS version. The cipher suites are specified as strings, for - example: "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA" (without quotes). + /** + Returns a list of supported cipher suites for the specified + SSL/TLS version. The cipher suites are specified as strings, for + example: "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA" (without quotes). - \param version the version of TLS to search for - */ - virtual QStringList supportedCipherSuites(const TLS::Version &version) const = 0; + \param version the version of TLS to search for + */ + virtual QStringList supportedCipherSuites(const TLS::Version &version) const = 0; - /** - Returns true if the provider supports compression - */ - virtual bool canCompress() const = 0; + /** + Returns true if the provider supports compression + */ + virtual bool canCompress() const = 0; - /** - Returns true if the provider supports server name indication - */ - virtual bool canSetHostName() const = 0; + /** + Returns true if the provider supports server name indication + */ + virtual bool canSetHostName() const = 0; - /** - Returns the maximum SSF supported by this provider - */ - virtual int maxSSF() const = 0; + /** + Returns the maximum SSF supported by this provider + */ + virtual int maxSSF() const = 0; - /** - Configure a new session + /** + Configure a new session - This function will be called before any other configuration - functions. + This function will be called before any other configuration + functions. - \param serverMode whether to operate as a server (true) or client (false) - \param hostName the hostname to use - \param compress whether to compress (true) or not (false) - */ - virtual void setup(bool serverMode, const QString &hostName, bool compress) = 0; + \param serverMode whether to operate as a server (true) or client (false) + \param hostName the hostname to use + \param compress whether to compress (true) or not (false) + */ + virtual void setup(bool serverMode, const QString &hostName, bool compress) = 0; - /** - Set the constraints of the session using SSF values + /** + Set the constraints of the session using SSF values - This function will be called before start(). + This function will be called before start(). - \param minSSF the minimum strength factor that is acceptable - \param maxSSF the maximum strength factor that is acceptable - */ - virtual void setConstraints(int minSSF, int maxSSF) = 0; + \param minSSF the minimum strength factor that is acceptable + \param maxSSF the maximum strength factor that is acceptable + */ + virtual void setConstraints(int minSSF, int maxSSF) = 0; - /** - \overload + /** + \overload - Set the constraints of the session using a cipher suite list + Set the constraints of the session using a cipher suite list - This function will be called before start(). + This function will be called before start(). - \param cipherSuiteList the list of cipher suites that may be used for - this session. + \param cipherSuiteList the list of cipher suites that may be used for + this session. - \sa supportedCipherSuites - */ - virtual void setConstraints(const QStringList &cipherSuiteList) = 0; + \sa supportedCipherSuites + */ + virtual void setConstraints(const QStringList &cipherSuiteList) = 0; - /** - Set the list of trusted certificates + /** + Set the list of trusted certificates - This function may be called at any time. + This function may be called at any time. - \param trusted the trusted certificates and CRLs to be used. - */ - virtual void setTrustedCertificates(const CertificateCollection &trusted) = 0; + \param trusted the trusted certificates and CRLs to be used. + */ + virtual void setTrustedCertificates(const CertificateCollection &trusted) = 0; - /** - Set the list of acceptable issuers + /** + Set the list of acceptable issuers - This function may be called at any time. + This function may be called at any time. - This function is for server mode only. + This function is for server mode only. - \param issuerList the list of issuers that may be used - */ - virtual void setIssuerList(const QList &issuerList) = 0; + \param issuerList the list of issuers that may be used + */ + virtual void setIssuerList(const QList &issuerList) = 0; - /** - Set the local certificate + /** + Set the local certificate - This function may be called at any time. + This function may be called at any time. - \param cert the certificate and associated trust chain - \param key the private key for the local certificate - */ - virtual void setCertificate(const CertificateChain &cert, const PrivateKey &key) = 0; + \param cert the certificate and associated trust chain + \param key the private key for the local certificate + */ + virtual void setCertificate(const CertificateChain &cert, const PrivateKey &key) = 0; - /** - Set the TLS session id, for session resuming + /** + Set the TLS session id, for session resuming - This function will be called before start(). + This function will be called before start(). - \param id the session identification - */ - virtual void setSessionId(const TLSSessionContext &id) = 0; + \param id the session identification + */ + virtual void setSessionId(const TLSSessionContext &id) = 0; - /** - Sets the session to the shutdown state. + /** + Sets the session to the shutdown state. - The actual shutdown operation will happen at a future call to - update(). + The actual shutdown operation will happen at a future call to + update(). - This function is for normal TLS only (not DTLS). - */ - virtual void shutdown() = 0; + This function is for normal TLS only (not DTLS). + */ + virtual void shutdown() = 0; - /** - Set the maximum transmission unit size + /** + Set the maximum transmission unit size - This function is for DTLS only. + This function is for DTLS only. - \param size the maximum number of bytes in a datagram - */ - virtual void setMTU(int size); + \param size the maximum number of bytes in a datagram + */ + virtual void setMTU(int size); - /** - Begins the session, starting with the handshake + /** + Begins the session, starting with the handshake - This function returns immediately, and completion is signaled with - the resultsReady() signal. + This function returns immediately, and completion is signaled with + the resultsReady() signal. - On completion, the result() function will return Success if the - TLS session is able to begin, or Error if there is a failure to - initialize the TLS subsystem. If successful, the session is now - in the handshake state, and update() will be called repeatedly - until the session ends. - */ - virtual void start() = 0; + On completion, the result() function will return Success if the + TLS session is able to begin, or Error if there is a failure to + initialize the TLS subsystem. If successful, the session is now + in the handshake state, and update() will be called repeatedly + until the session ends. + */ + virtual void start() = 0; - /** - Performs one iteration of the TLS session processing + /** + Performs one iteration of the TLS session processing - This function returns immediately, and completion is signaled with - the resultsReady() signal. + This function returns immediately, and completion is signaled with + the resultsReady() signal. - If the session is in a handshake state, result() and to_net() will - be valid. If result() is Success, then the session is now in the - connected state. + If the session is in a handshake state, result() and to_net() will + be valid. If result() is Success, then the session is now in the + connected state. - If the session is in a shutdown state, result() and to_net() will - be valid. If result() is Success, then the session has ended. + If the session is in a shutdown state, result() and to_net() will + be valid. If result() is Success, then the session has ended. - If the session is in a connected state, result(), to_net(), - encoded(), to_app(), and eof() are valid. The result() function - will return Success or Error. Note that eof() does not apply - to DTLS. + If the session is in a connected state, result(), to_net(), + encoded(), to_app(), and eof() are valid. The result() function + will return Success or Error. Note that eof() does not apply + to DTLS. - For DTLS, this function operates with single packets. Many - update() operations must be performed repeatedly to exchange - multiple packets. + For DTLS, this function operates with single packets. Many + update() operations must be performed repeatedly to exchange + multiple packets. - \param from_net the data from the "other side" of the connection - \param from_app the data from the application of the protocol - */ - virtual void update(const QByteArray &from_net, const QByteArray &from_app) = 0; + \param from_net the data from the "other side" of the connection + \param from_app the data from the application of the protocol + */ + virtual void update(const QByteArray &from_net, const QByteArray &from_app) = 0; - /** - Waits for a start() or update() operation to complete. In this - case, the resultsReady() signal is not emitted. Returns true if - the operation completed or false if this function times out. + /** + Waits for a start() or update() operation to complete. In this + case, the resultsReady() signal is not emitted. Returns true if + the operation completed or false if this function times out. - This function is blocking. + This function is blocking. - \param msecs number of milliseconds to wait (-1 to wait forever) - */ - virtual bool waitForResultsReady(int msecs) = 0; + \param msecs number of milliseconds to wait (-1 to wait forever) + */ + virtual bool waitForResultsReady(int msecs) = 0; - /** - Returns the result code of an operation - */ - virtual Result result() const = 0; + /** + Returns the result code of an operation + */ + virtual Result result() const = 0; - /** - Returns data that should be sent across the network - */ - virtual QByteArray to_net() = 0; + /** + Returns data that should be sent across the network + */ + virtual QByteArray to_net() = 0; - /** - Returns the number of bytes of plaintext data that is encoded - inside of to_net() - */ - virtual int encoded() const = 0; + /** + Returns the number of bytes of plaintext data that is encoded + inside of to_net() + */ + virtual int encoded() const = 0; - /** - Returns data that is decoded from the network and should be - processed by the application - */ - virtual QByteArray to_app() = 0; + /** + Returns data that is decoded from the network and should be + processed by the application + */ + virtual QByteArray to_app() = 0; - /** - Returns true if the peer has closed the stream - */ - virtual bool eof() const = 0; + /** + Returns true if the peer has closed the stream + */ + virtual bool eof() const = 0; - /** - Returns true if the TLS client hello has been received + /** + Returns true if the TLS client hello has been received - This is only valid if a handshake is in progress or - completed. - */ - virtual bool clientHelloReceived() const = 0; + This is only valid if a handshake is in progress or + completed. + */ + virtual bool clientHelloReceived() const = 0; - /** - Returns true if the TLS server hello has been received + /** + Returns true if the TLS server hello has been received - This is only valid if a handshake is in progress or completed. - */ - virtual bool serverHelloReceived() const = 0; + This is only valid if a handshake is in progress or completed. + */ + virtual bool serverHelloReceived() const = 0; - /** - Returns the host name sent by the client using server name - indication (server mode only) + /** + Returns the host name sent by the client using server name + indication (server mode only) - This is only valid if a handshake is in progress or completed. - */ - virtual QString hostName() const = 0; + This is only valid if a handshake is in progress or completed. + */ + virtual QString hostName() const = 0; - /** - Returns true if the peer is requesting a certificate + /** + Returns true if the peer is requesting a certificate - This is only valid if a handshake is in progress or completed. - */ - virtual bool certificateRequested() const = 0; + This is only valid if a handshake is in progress or completed. + */ + virtual bool certificateRequested() const = 0; - /** - Returns the issuer list sent by the server (client mode only) + /** + Returns the issuer list sent by the server (client mode only) - This is only valid if a handshake is in progress or completed. - */ - virtual QList issuerList() const = 0; + This is only valid if a handshake is in progress or completed. + */ + virtual QList issuerList() const = 0; - /** - Returns the QCA::Validity of the peer certificate + /** + Returns the QCA::Validity of the peer certificate - This is only valid if a handshake is completed. - */ - virtual Validity peerCertificateValidity() const = 0; + This is only valid if a handshake is completed. + */ + virtual Validity peerCertificateValidity() const = 0; - /** - Returns the peer certificate chain + /** + Returns the peer certificate chain - This is only valid if a handshake is completed. - */ - virtual CertificateChain peerCertificateChain() const = 0; + This is only valid if a handshake is completed. + */ + virtual CertificateChain peerCertificateChain() const = 0; - /** - Returns information about the active TLS session + /** + Returns information about the active TLS session - This is only valid if a handshake is completed. - */ - virtual SessionInfo sessionInfo() const = 0; + This is only valid if a handshake is completed. + */ + virtual SessionInfo sessionInfo() const = 0; - /** - Returns any unprocessed network input data + /** + Returns any unprocessed network input data - This is only valid after a successful shutdown. - */ - virtual QByteArray unprocessed() = 0; + This is only valid after a successful shutdown. + */ + virtual QByteArray unprocessed() = 0; Q_SIGNALS: - /** - Emit this when a start() or update() operation has completed. - */ - void resultsReady(); - - /** - Emit this to force the application to call update(), even with - empty arguments. - */ - void dtlsTimeout(); + /** + Emit this when a start() or update() operation has completed. + */ + void resultsReady(); + + /** + Emit this to force the application to call update(), even with + empty arguments. + */ + void dtlsTimeout(); }; /** @@ -2500,293 +2500,292 @@ */ class QCA_EXPORT SASLContext : public Provider::Context { - Q_OBJECT + Q_OBJECT public: - /** - \class QCA::SASLContext::HostPort qcaprovider.h QtCrypto - - Convenience class to hold an IP address and an associated port - - For efficiency and simplicity, the members are directly accessed. - - \ingroup ProviderAPI - */ - class HostPort - { - public: - /** - The IP address - */ - QString addr; - - /** - The port - */ - quint16 port; - }; - - /** - Result of a SASL operation - */ - enum Result - { - Success, ///< Operation completed - Error, ///< Operation failed - Params, ///< Parameters are needed to complete authentication - AuthCheck, ///< Client login can be inspected (server only) - Continue ///< More steps needed to complete authentication - }; - - /** - Standard constructor - - \param p the Provider associated with this context - */ - SASLContext(Provider *p) : Provider::Context(p, QStringLiteral("sasl")) {} - - /** - Reset the object to its initial state - */ - virtual void reset() = 0; - - /** - Configure a new session - - This function will be called before any other configuration - functions. - - \param service the name of the network service being provided by - this application, which can be used by the SASL system for policy - control. Examples: "imap", "xmpp" - \param host the hostname that the application is interacting with - or as - \param local pointer to a HostPort representing the local end of a - network socket, or 0 if this information is unknown or not - available - \param remote pointer to a HostPort representing the peer end of a - network socket, or 0 if this information is unknown or not - available - \param ext_id the id to be used for SASL EXTERNAL (client only) - \param ext_ssf the SSF of the external authentication channel - (client only) - */ - virtual void setup(const QString &service, const QString &host, const HostPort *local, const HostPort *remote, const QString &ext_id, int ext_ssf) = 0; - - /** - Set the constraints of the session using SSF values - - This function will be called before startClient() or - startServer(). - - \param f the flags to use - \param minSSF the minimum strength factor that is acceptable - \param maxSSF the maximum strength factor that is acceptable - */ - virtual void setConstraints(SASL::AuthFlags f, int minSSF, int maxSSF) = 0; - - /** - Begins the session in client mode, starting with the - authentication - - This function returns immediately, and completion is signaled with - the resultsReady() signal. - - On completion, result(), mech(), haveClientInit(), and stepData() - will be valid. If result() is Success, then the session is now in - the connected state. - - \param mechlist the list of mechanisms - \param allowClientSendFirst whether the client sends first (true) or the server - sends first (false) - */ - virtual void startClient(const QStringList &mechlist, bool allowClientSendFirst) = 0; - - /** - Begins the session in server mode, starting with the - authentication - - This function returns immediately, and completion is signaled with - the resultsReady() signal. - - On completion, result() and mechlist() will be valid. The - result() function will return Success or Error. If the result is - Success, then serverFirstStep() will be called next. - - \param realm the realm to authenticate in - \param disableServerSendLast whether the client sends first (true) - or the server sends first (false) - */ - virtual void startServer(const QString &realm, bool disableServerSendLast) = 0; - - /** - Finishes server startup - - This function returns immediately, and completion is signaled with - the resultsReady() signal. - - On completion, result() and stepData() will be valid. If result() - is Success, then the session is now in the connected state. - - \param mech the mechanism to use - \param clientInit initial data from the client, or 0 if there is - no such data - */ - virtual void serverFirstStep(const QString &mech, const QByteArray *clientInit) = 0; - - /** - Perform another step of the SASL authentication - - This function returns immediately, and completion is signaled with - the resultsReady() signal. - - On completion, result() and stepData() will be valid. - - \param from_net the data from the "other side" of the protocol - to be used for the next step. - */ - virtual void nextStep(const QByteArray &from_net) = 0; - - /** - Attempt the most recent operation again. This is used if the - result() of an operation is Params or AuthCheck. - - This function returns immediately, and completion is signaled with - the resultsReady() signal. - - On completion, result() and stepData() will be valid. - */ - virtual void tryAgain() = 0; - - /** - Performs one iteration of the SASL security layer processing - - This function returns immediately, and completion is signaled with - the resultsReady() signal. - - On completion, result(), to_net(), encoded(), and to_app() will be - valid. The result() function will return Success or Error. - - \param from_net the data from the "other side" of the protocol - \param from_app the data from the application of the protocol - */ - virtual void update(const QByteArray &from_net, const QByteArray &from_app) = 0; - - /** - Waits for a startClient(), startServer(), serverFirstStep(), - nextStep(), tryAgain(), or update() operation to complete. In - this case, the resultsReady() signal is not emitted. Returns true - if the operation completed or false if this function times out. - - This function is blocking. - - \param msecs number of milliseconds to wait (-1 to wait forever) - */ - virtual bool waitForResultsReady(int msecs) = 0; + /** + \class QCA::SASLContext::HostPort qcaprovider.h QtCrypto + + Convenience class to hold an IP address and an associated port + + For efficiency and simplicity, the members are directly accessed. + + \ingroup ProviderAPI + */ + class HostPort + { + public: + /** + The IP address + */ + QString addr; + + /** + The port + */ + quint16 port; + }; + + /** + Result of a SASL operation + */ + enum Result { + Success, ///< Operation completed + Error, ///< Operation failed + Params, ///< Parameters are needed to complete authentication + AuthCheck, ///< Client login can be inspected (server only) + Continue ///< More steps needed to complete authentication + }; + + /** + Standard constructor + + \param p the Provider associated with this context + */ + SASLContext(Provider *p) : Provider::Context(p, QStringLiteral("sasl")) {} + + /** + Reset the object to its initial state + */ + virtual void reset() = 0; + + /** + Configure a new session + + This function will be called before any other configuration + functions. + + \param service the name of the network service being provided by + this application, which can be used by the SASL system for policy + control. Examples: "imap", "xmpp" + \param host the hostname that the application is interacting with + or as + \param local pointer to a HostPort representing the local end of a + network socket, or 0 if this information is unknown or not + available + \param remote pointer to a HostPort representing the peer end of a + network socket, or 0 if this information is unknown or not + available + \param ext_id the id to be used for SASL EXTERNAL (client only) + \param ext_ssf the SSF of the external authentication channel + (client only) + */ + virtual void setup(const QString &service, const QString &host, const HostPort *local, const HostPort *remote, const QString &ext_id, int ext_ssf) = 0; + + /** + Set the constraints of the session using SSF values + + This function will be called before startClient() or + startServer(). + + \param f the flags to use + \param minSSF the minimum strength factor that is acceptable + \param maxSSF the maximum strength factor that is acceptable + */ + virtual void setConstraints(SASL::AuthFlags f, int minSSF, int maxSSF) = 0; + + /** + Begins the session in client mode, starting with the + authentication + + This function returns immediately, and completion is signaled with + the resultsReady() signal. + + On completion, result(), mech(), haveClientInit(), and stepData() + will be valid. If result() is Success, then the session is now in + the connected state. + + \param mechlist the list of mechanisms + \param allowClientSendFirst whether the client sends first (true) or the server + sends first (false) + */ + virtual void startClient(const QStringList &mechlist, bool allowClientSendFirst) = 0; + + /** + Begins the session in server mode, starting with the + authentication + + This function returns immediately, and completion is signaled with + the resultsReady() signal. + + On completion, result() and mechlist() will be valid. The + result() function will return Success or Error. If the result is + Success, then serverFirstStep() will be called next. + + \param realm the realm to authenticate in + \param disableServerSendLast whether the client sends first (true) + or the server sends first (false) + */ + virtual void startServer(const QString &realm, bool disableServerSendLast) = 0; + + /** + Finishes server startup + + This function returns immediately, and completion is signaled with + the resultsReady() signal. + + On completion, result() and stepData() will be valid. If result() + is Success, then the session is now in the connected state. + + \param mech the mechanism to use + \param clientInit initial data from the client, or 0 if there is + no such data + */ + virtual void serverFirstStep(const QString &mech, const QByteArray *clientInit) = 0; + + /** + Perform another step of the SASL authentication + + This function returns immediately, and completion is signaled with + the resultsReady() signal. + + On completion, result() and stepData() will be valid. + + \param from_net the data from the "other side" of the protocol + to be used for the next step. + */ + virtual void nextStep(const QByteArray &from_net) = 0; + + /** + Attempt the most recent operation again. This is used if the + result() of an operation is Params or AuthCheck. + + This function returns immediately, and completion is signaled with + the resultsReady() signal. + + On completion, result() and stepData() will be valid. + */ + virtual void tryAgain() = 0; + + /** + Performs one iteration of the SASL security layer processing + + This function returns immediately, and completion is signaled with + the resultsReady() signal. + + On completion, result(), to_net(), encoded(), and to_app() will be + valid. The result() function will return Success or Error. + + \param from_net the data from the "other side" of the protocol + \param from_app the data from the application of the protocol + */ + virtual void update(const QByteArray &from_net, const QByteArray &from_app) = 0; + + /** + Waits for a startClient(), startServer(), serverFirstStep(), + nextStep(), tryAgain(), or update() operation to complete. In + this case, the resultsReady() signal is not emitted. Returns true + if the operation completed or false if this function times out. + + This function is blocking. + + \param msecs number of milliseconds to wait (-1 to wait forever) + */ + virtual bool waitForResultsReady(int msecs) = 0; - /** - Returns the result code of an operation - */ - virtual Result result() const = 0; + /** + Returns the result code of an operation + */ + virtual Result result() const = 0; - /** - Returns the mechanism list (server mode only) - */ - virtual QStringList mechlist() const = 0; - - /** - Returns the mechanism selected - */ - virtual QString mech() const = 0; - - /** - Returns true if the client has initialization data - */ - virtual bool haveClientInit() const = 0; + /** + Returns the mechanism list (server mode only) + */ + virtual QStringList mechlist() const = 0; + + /** + Returns the mechanism selected + */ + virtual QString mech() const = 0; + + /** + Returns true if the client has initialization data + */ + virtual bool haveClientInit() const = 0; - /** - Returns an authentication payload for to be transmitted over the - network - */ - virtual QByteArray stepData() const = 0; - - /** - Returns data that should be sent across the network (for the - security layer) - */ - virtual QByteArray to_net() = 0; + /** + Returns an authentication payload for to be transmitted over the + network + */ + virtual QByteArray stepData() const = 0; + + /** + Returns data that should be sent across the network (for the + security layer) + */ + virtual QByteArray to_net() = 0; - /** - Returns the number of bytes of plaintext data that is encoded - inside of to_net() - */ - virtual int encoded() const = 0; + /** + Returns the number of bytes of plaintext data that is encoded + inside of to_net() + */ + virtual int encoded() const = 0; - /** - Returns data that is decoded from the network and should be - processed by the application - */ - virtual QByteArray to_app() = 0; + /** + Returns data that is decoded from the network and should be + processed by the application + */ + virtual QByteArray to_app() = 0; - /** - Returns the SSF of the active SASL session - - This is only valid after authentication success. - */ - virtual int ssf() const = 0; - - /** - Returns the reason for failure, if the authentication was not - successful. - - This is only valid after authentication failure. - */ - virtual SASL::AuthCondition authCondition() const = 0; - - /** - Returns the needed/optional client parameters - - This is only valid after receiving the Params result code. - */ - virtual SASL::Params clientParams() const = 0; - - /** - Set some of the client parameters (pass 0 to not set a field) - - \param user the user name - \param authzid the authorization name / role - \param pass the password - \param realm the realm to authenticate in - */ - virtual void setClientParams(const QString *user, const QString *authzid, const SecureArray *pass, const QString *realm) = 0; - - /** - Returns the realm list (client mode only) - - This is only valid after receiving the Params result code and - SASL::Params::canSendRealm is set to true. - */ - virtual QStringList realmlist() const = 0; - - /** - Returns the username attempting to authenticate (server mode only) - - This is only valid after receiving the AuthCheck result code. - */ - virtual QString username() const = 0; - - /** - Returns the authzid attempting to authorize (server mode only) - - This is only valid after receiving the AuthCheck result code. - */ - virtual QString authzid() const = 0; + /** + Returns the SSF of the active SASL session + + This is only valid after authentication success. + */ + virtual int ssf() const = 0; + + /** + Returns the reason for failure, if the authentication was not + successful. + + This is only valid after authentication failure. + */ + virtual SASL::AuthCondition authCondition() const = 0; + + /** + Returns the needed/optional client parameters + + This is only valid after receiving the Params result code. + */ + virtual SASL::Params clientParams() const = 0; + + /** + Set some of the client parameters (pass 0 to not set a field) + + \param user the user name + \param authzid the authorization name / role + \param pass the password + \param realm the realm to authenticate in + */ + virtual void setClientParams(const QString *user, const QString *authzid, const SecureArray *pass, const QString *realm) = 0; + + /** + Returns the realm list (client mode only) + + This is only valid after receiving the Params result code and + SASL::Params::canSendRealm is set to true. + */ + virtual QStringList realmlist() const = 0; + + /** + Returns the username attempting to authenticate (server mode only) + + This is only valid after receiving the AuthCheck result code. + */ + virtual QString username() const = 0; + + /** + Returns the authzid attempting to authorize (server mode only) + + This is only valid after receiving the AuthCheck result code. + */ + virtual QString authzid() const = 0; Q_SIGNALS: - /** - Emit this when a startClient(), startServer(), serverFirstStep(), - nextStep(), tryAgain(), or update() operation has completed. - */ - void resultsReady(); + /** + Emit this when a startClient(), startServer(), serverFirstStep(), + nextStep(), tryAgain(), or update() operation has completed. + */ + void resultsReady(); }; /** @@ -2802,176 +2801,175 @@ */ class QCA_EXPORT MessageContext : public Provider::Context { - Q_OBJECT + Q_OBJECT public: - /** - The type of operation being performed - */ - enum Operation - { - Encrypt, ///< Encrypt operation - Decrypt, ///< Decrypt (or Decrypt and Verify) operation - Sign, ///< Sign operation - Verify, ///< Verify operation - SignAndEncrypt ///< Sign and Encrypt operation - }; - - /** - Standard constructor - - \param p the Provider associated with this context - \param type the name of the type of secure message to be created - */ - MessageContext(Provider *p, const QString &type) : Provider::Context(p, type) {} - - /** - Returns true if the provider supports multiple signers for - signature creation or signature verification - */ - virtual bool canSignMultiple() const = 0; - - /** - The type of secure message (e.g. PGP or CMS) - */ - virtual SecureMessage::Type type() const = 0; - - /** - Reset the object to its initial state - */ - virtual void reset() = 0; - - /** - Configure a new encrypting operation - - \param keys the keys to be used for encryption. - */ - virtual void setupEncrypt(const SecureMessageKeyList &keys) = 0; - - /** - Configure a new signing operation - - \param keys the keys to use for signing - \param m the mode to sign in - \param bundleSigner whether to bundle the signing keys (true) or not (false) - \param smime whether to use smime format (true) or not (false) - */ - virtual void setupSign(const SecureMessageKeyList &keys, SecureMessage::SignMode m, bool bundleSigner, bool smime) = 0; - - /** - Configure a new verify operation - - \param detachedSig the detached signature to use (if applicable) for verification - */ - virtual void setupVerify(const QByteArray &detachedSig) = 0; - - /** - Begins the secure message operation - - This function returns immediately. - - If there is input data, update() will be called (potentially - repeatedly) afterwards. Emit updated() if there is data to - read, if input data has been accepted, or if the operation has - finished. - - \param f the format of the message to be produced - \param op the operation to be performed - */ - virtual void start(SecureMessage::Format f, Operation op) = 0; - - /** - Provide input to the message operation - - \param in the data to use for the message operation - */ - virtual void update(const QByteArray &in) = 0; - - /** - Extract output from the message operation - */ - virtual QByteArray read() = 0; - - /** - Returns the number of input bytes accepted since the last call to - update() - */ - virtual int written() = 0; - - /** - Indicates the end of input - */ - virtual void end() = 0; - - /** - Returns true if the operation has finished, otherwise false - */ - virtual bool finished() const = 0; - - /** - Waits for the secure message operation to complete. In this case, - the updated() signal is not emitted. Returns true if the - operation completed or false if this function times out. - - This function is blocking. - - \param msecs number of milliseconds to wait (-1 to wait forever) - */ - virtual bool waitForFinished(int msecs) = 0; - - /** - Returns true if the operation was successful - - This is only valid if the operation has finished. - */ - virtual bool success() const = 0; - - /** - Returns the reason for failure, if the operation was not - successful + /** + The type of operation being performed + */ + enum Operation { + Encrypt, ///< Encrypt operation + Decrypt, ///< Decrypt (or Decrypt and Verify) operation + Sign, ///< Sign operation + Verify, ///< Verify operation + SignAndEncrypt ///< Sign and Encrypt operation + }; + + /** + Standard constructor + + \param p the Provider associated with this context + \param type the name of the type of secure message to be created + */ + MessageContext(Provider *p, const QString &type) : Provider::Context(p, type) {} + + /** + Returns true if the provider supports multiple signers for + signature creation or signature verification + */ + virtual bool canSignMultiple() const = 0; + + /** + The type of secure message (e.g. PGP or CMS) + */ + virtual SecureMessage::Type type() const = 0; + + /** + Reset the object to its initial state + */ + virtual void reset() = 0; + + /** + Configure a new encrypting operation + + \param keys the keys to be used for encryption. + */ + virtual void setupEncrypt(const SecureMessageKeyList &keys) = 0; + + /** + Configure a new signing operation + + \param keys the keys to use for signing + \param m the mode to sign in + \param bundleSigner whether to bundle the signing keys (true) or not (false) + \param smime whether to use smime format (true) or not (false) + */ + virtual void setupSign(const SecureMessageKeyList &keys, SecureMessage::SignMode m, bool bundleSigner, bool smime) = 0; + + /** + Configure a new verify operation + + \param detachedSig the detached signature to use (if applicable) for verification + */ + virtual void setupVerify(const QByteArray &detachedSig) = 0; + + /** + Begins the secure message operation + + This function returns immediately. + + If there is input data, update() will be called (potentially + repeatedly) afterwards. Emit updated() if there is data to + read, if input data has been accepted, or if the operation has + finished. + + \param f the format of the message to be produced + \param op the operation to be performed + */ + virtual void start(SecureMessage::Format f, Operation op) = 0; + + /** + Provide input to the message operation + + \param in the data to use for the message operation + */ + virtual void update(const QByteArray &in) = 0; + + /** + Extract output from the message operation + */ + virtual QByteArray read() = 0; + + /** + Returns the number of input bytes accepted since the last call to + update() + */ + virtual int written() = 0; + + /** + Indicates the end of input + */ + virtual void end() = 0; + + /** + Returns true if the operation has finished, otherwise false + */ + virtual bool finished() const = 0; + + /** + Waits for the secure message operation to complete. In this case, + the updated() signal is not emitted. Returns true if the + operation completed or false if this function times out. + + This function is blocking. + + \param msecs number of milliseconds to wait (-1 to wait forever) + */ + virtual bool waitForFinished(int msecs) = 0; + + /** + Returns true if the operation was successful + + This is only valid if the operation has finished. + */ + virtual bool success() const = 0; + + /** + Returns the reason for failure, if the operation was not + successful - This is only valid if the operation has finished. - */ - virtual SecureMessage::Error errorCode() const = 0; + This is only valid if the operation has finished. + */ + virtual SecureMessage::Error errorCode() const = 0; - /** - Returns the signature, in the case of a detached signature - operation + /** + Returns the signature, in the case of a detached signature + operation - This is only valid if the operation has finished. - */ - virtual QByteArray signature() const = 0; + This is only valid if the operation has finished. + */ + virtual QByteArray signature() const = 0; - /** - Returns the name of the hash used to generate the signature, in - the case of a signature operation + /** + Returns the name of the hash used to generate the signature, in + the case of a signature operation - This is only valid if the operation has finished. - */ - virtual QString hashName() const = 0; + This is only valid if the operation has finished. + */ + virtual QString hashName() const = 0; - /** - Returns a list of signatures, in the case of a verify or decrypt - and verify operation + /** + Returns a list of signatures, in the case of a verify or decrypt + and verify operation - This is only valid if the operation has finished. - */ - virtual SecureMessageSignatureList signers() const = 0; + This is only valid if the operation has finished. + */ + virtual SecureMessageSignatureList signers() const = 0; - /** - Returns any diagnostic text for the operation, potentially useful - to show the user in the event the operation is unsuccessful. For - example, this could be the stderr output of gpg. + /** + Returns any diagnostic text for the operation, potentially useful + to show the user in the event the operation is unsuccessful. For + example, this could be the stderr output of gpg. - This is only valid if the operation has finished. - */ - virtual QString diagnosticText() const; + This is only valid if the operation has finished. + */ + virtual QString diagnosticText() const; Q_SIGNALS: - /** - Emitted when there is data to read, if input data has been - accepted, or if the operation has finished - */ - void updated(); + /** + Emitted when there is data to read, if input data has been + accepted, or if the operation has finished + */ + void updated(); }; /** @@ -2987,53 +2985,53 @@ */ class QCA_EXPORT SMSContext : public BasicContext { - Q_OBJECT + Q_OBJECT public: - /** - Standard constructor + /** + Standard constructor - \param p the provider associated with this context - \param type the name of the type of secure message system - */ - SMSContext(Provider *p, const QString &type) : BasicContext(p, type) {} + \param p the provider associated with this context + \param type the name of the type of secure message system + */ + SMSContext(Provider *p, const QString &type) : BasicContext(p, type) {} - /** - Set the trusted certificates and for this secure message system, - to be used for validation + /** + Set the trusted certificates and for this secure message system, + to be used for validation - The collection may also contain CRLs. + The collection may also contain CRLs. - This function is only valid for CMS. + This function is only valid for CMS. - \param trusted a set of trusted certificates and CRLs. - */ - virtual void setTrustedCertificates(const CertificateCollection &trusted); + \param trusted a set of trusted certificates and CRLs. + */ + virtual void setTrustedCertificates(const CertificateCollection &trusted); - /** - Set the untrusted certificates and CRLs for this secure message - system, to be used for validation + /** + Set the untrusted certificates and CRLs for this secure message + system, to be used for validation - This function is only valid for CMS. + This function is only valid for CMS. - \param untrusted a set of untrusted certificates and CRLs. - */ - virtual void setUntrustedCertificates(const CertificateCollection &untrusted); + \param untrusted a set of untrusted certificates and CRLs. + */ + virtual void setUntrustedCertificates(const CertificateCollection &untrusted); - /** - Set the private keys for this secure message system, to be used - for decryption + /** + Set the private keys for this secure message system, to be used + for decryption - This function is only valid for CMS. + This function is only valid for CMS. - \param keys the keys to be used for decryption - */ - virtual void setPrivateKeys(const QList &keys); + \param keys the keys to be used for decryption + */ + virtual void setPrivateKeys(const QList &keys); - /** - Create a new message object for this system. The caller is - responsible for deleting it. - */ - virtual MessageContext *createMessage() = 0; + /** + Create a new message object for this system. The caller is + responsible for deleting it. + */ + virtual MessageContext *createMessage() = 0; }; } diff --git a/include/QtCrypto/qpipe.h b/include/QtCrypto/qpipe.h --- a/include/QtCrypto/qpipe.h +++ b/include/QtCrypto/qpipe.h @@ -59,8 +59,8 @@ // to completely decode (no partial characters). Likewise, writes must // not contain partial characters. -namespace QCA { - +namespace QCA +{ /** \class QPipeDevice qpipe.h QtCrypto @@ -74,136 +74,135 @@ */ class QCA_EXPORT QPipeDevice : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - The type of device - */ - enum Type - { - Read, ///< The pipe end can be read from - Write ///< The pipe end can be written to - }; + /** + The type of device + */ + enum Type { + Read, ///< The pipe end can be read from + Write ///< The pipe end can be written to + }; - /** - Standard constructor + /** + Standard constructor - \param parent the parent object to this object - */ - QPipeDevice(QObject *parent = 0); - ~QPipeDevice(); + \param parent the parent object to this object + */ + QPipeDevice(QObject *parent = 0); + ~QPipeDevice(); - /** - The Type of the pipe device (that is, read or write) - */ - Type type() const; + /** + The Type of the pipe device (that is, read or write) + */ + Type type() const; - /** - Test whether this object corresponds to a valid pipe - */ - bool isValid() const; + /** + Test whether this object corresponds to a valid pipe + */ + bool isValid() const; - /** - The low level identification for this pipe. + /** + The low level identification for this pipe. - On Windows, this is a HANDLE. On Unix, this is a file descriptor (i.e. integer). + On Windows, this is a HANDLE. On Unix, this is a file descriptor (i.e. integer). - Code using this method should be carefully tested for portability. + Code using this method should be carefully tested for portability. - \sa idAsInt - */ - Q_PIPE_ID id() const; + \sa idAsInt + */ + Q_PIPE_ID id() const; - /** - The low level identification for this pipe, returned as an integer. + /** + The low level identification for this pipe, returned as an integer. - Code using this method should be carefully tested for portability. + Code using this method should be carefully tested for portability. - \sa id(). - */ - int idAsInt() const; + \sa id(). + */ + int idAsInt() const; - /** - Take over an existing pipe id, closing the old pipe if any. + /** + Take over an existing pipe id, closing the old pipe if any. - \param id the identification of the pipe end to take over. - \param t the type of pipe end (read or write). - */ - void take(Q_PIPE_ID id, Type t); + \param id the identification of the pipe end to take over. + \param t the type of pipe end (read or write). + */ + void take(Q_PIPE_ID id, Type t); - /** - Enable the pipe for reading or writing (depending on Type) - */ - void enable(); + /** + Enable the pipe for reading or writing (depending on Type) + */ + void enable(); - /** - Close the pipe end. - */ - void close(); + /** + Close the pipe end. + */ + void close(); - /** - Release the pipe end, but do not close it. - */ - void release(); + /** + Release the pipe end, but do not close it. + */ + void release(); - /** - Set the pipe end to be inheritable + /** + Set the pipe end to be inheritable - \note On Windows, this operation changes the pipe end id value. + \note On Windows, this operation changes the pipe end id value. - \param enabled whether the pipe is inheritable (true) or not (false) - */ - bool setInheritable(bool enabled); + \param enabled whether the pipe is inheritable (true) or not (false) + */ + bool setInheritable(bool enabled); - /** - Obtain the number of bytes available to be read. - */ - int bytesAvailable() const; + /** + Obtain the number of bytes available to be read. + */ + int bytesAvailable() const; - /** - Read from the pipe end + /** + Read from the pipe end - \param data where to put the data that has been read - \param maxsize the maximum number of bytes to be read. + \param data where to put the data that has been read + \param maxsize the maximum number of bytes to be read. - \return the actual number of bytes read, 0 on end-of-file, or -1 on error. - */ - int read(char *data, int maxsize); + \return the actual number of bytes read, 0 on end-of-file, or -1 on error. + */ + int read(char *data, int maxsize); - /** - Write to the pipe end. + /** + Write to the pipe end. - \param data the source of the data to be written - \param size the number of bytes in the data to be written + \param data the source of the data to be written + \param size the number of bytes in the data to be written - \note the data source must remain valid + \note the data source must remain valid - \return the number of bytes written, or -1 on error. - */ - int write(const char *data, int size); + \return the number of bytes written, or -1 on error. + */ + int write(const char *data, int size); - /** - The result of a write operation + /** + The result of a write operation - \param written if not null, this will be set to the number of - bytes written in the last operation. + \param written if not null, this will be set to the number of + bytes written in the last operation. - \return 0 on success (all data written), or -1 on error - */ - int writeResult(int *written) const; + \return 0 on success (all data written), or -1 on error + */ + int writeResult(int *written) const; Q_SIGNALS: - /** - Emitted when the pipe end can be read from or written to (depending on its Type). - */ - void notify(); + /** + Emitted when the pipe end can be read from or written to (depending on its Type). + */ + void notify(); private: - Q_DISABLE_COPY(QPipeDevice) + Q_DISABLE_COPY(QPipeDevice) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -217,248 +216,247 @@ */ class QCA_EXPORT QPipeEnd : public QObject { - Q_OBJECT + Q_OBJECT public: - /** - The type of error - */ - enum Error - { - ErrorEOF, ///< End of file error - ErrorBroken ///< Broken pipe error - }; + /** + The type of error + */ + enum Error { + ErrorEOF, ///< End of file error + ErrorBroken ///< Broken pipe error + }; - /** - Standard constructor + /** + Standard constructor - \param parent the parent object for this object - */ - QPipeEnd(QObject *parent = 0); + \param parent the parent object for this object + */ + QPipeEnd(QObject *parent = 0); - ~QPipeEnd(); + ~QPipeEnd(); - /** - Reset the pipe end to an inactive state - */ - void reset(); + /** + Reset the pipe end to an inactive state + */ + void reset(); - /** - The type of pipe end (either read or write) - */ - QPipeDevice::Type type() const; + /** + The type of pipe end (either read or write) + */ + QPipeDevice::Type type() const; - /** - Determine whether the pipe end is valid. + /** + Determine whether the pipe end is valid. - \note This does not mean the pipe is ready to be used - you - may need to call enable() first - */ - bool isValid() const; + \note This does not mean the pipe is ready to be used - you + may need to call enable() first + */ + bool isValid() const; - /** - Pipe identification - */ - Q_PIPE_ID id() const; + /** + Pipe identification + */ + Q_PIPE_ID id() const; - /** - Pipe identification - */ - int idAsInt() const; + /** + Pipe identification + */ + int idAsInt() const; - /** - Take over an existing pipe handle + /** + Take over an existing pipe handle - \param id the pipe handle - \param t the type of the pipe (read or write) - */ - void take(Q_PIPE_ID id, QPipeDevice::Type t); + \param id the pipe handle + \param t the type of the pipe (read or write) + */ + void take(Q_PIPE_ID id, QPipeDevice::Type t); #ifdef QPIPE_SECURE - /** - Sets whether the pipe uses secure memory for read/write + /** + Sets whether the pipe uses secure memory for read/write - Enabling this may reduce performance, and it should only be used if - sensitive data is being transmitted (such as a passphrase). + Enabling this may reduce performance, and it should only be used if + sensitive data is being transmitted (such as a passphrase). - \param secure whether the pipe uses secure memory (true) or not (false). - */ - void setSecurityEnabled(bool secure); + \param secure whether the pipe uses secure memory (true) or not (false). + */ + void setSecurityEnabled(bool secure); #endif - /** - Enable the endpoint for the pipe + /** + Enable the endpoint for the pipe - When an endpoint is created, it is not - able to be used until it is enabled. - */ - void enable(); + When an endpoint is created, it is not + able to be used until it is enabled. + */ + void enable(); - /** - Close the end of the pipe + /** + Close the end of the pipe - \sa closed() - */ - void close(); + \sa closed() + */ + void close(); - /** - Let go of the active pipe handle, but don't close it + /** + Let go of the active pipe handle, but don't close it - Use this before destructing QPipeEnd, if you don't want the pipe - to automatically close. - */ - void release(); + Use this before destructing QPipeEnd, if you don't want the pipe + to automatically close. + */ + void release(); - /** - Sets whether the pipe should be inheritable to child processes + /** + Sets whether the pipe should be inheritable to child processes - Returns true if inheritability was successfully changed, otherwise - false. + Returns true if inheritability was successfully changed, otherwise + false. - \param enabled whether the pipe is inheritable (true) or not (false). - */ - bool setInheritable(bool enabled); + \param enabled whether the pipe is inheritable (true) or not (false). + */ + bool setInheritable(bool enabled); - /** - Clear the contents of the pipe, and invalidate the pipe - */ - void finalize(); + /** + Clear the contents of the pipe, and invalidate the pipe + */ + void finalize(); - /** - Clear the contents of the pipe, and release the pipe - */ - void finalizeAndRelease(); + /** + Clear the contents of the pipe, and release the pipe + */ + void finalizeAndRelease(); - /** - Determine how many bytes are available to be read. + /** + Determine how many bytes are available to be read. - This only makes sense at the read end of the pipe + This only makes sense at the read end of the pipe - \sa readyRead() for a signal that can be used to determine - when there are bytes available to read. - */ - int bytesAvailable() const; + \sa readyRead() for a signal that can be used to determine + when there are bytes available to read. + */ + int bytesAvailable() const; - /** - Returns the number of bytes pending to write + /** + Returns the number of bytes pending to write - This only makes sense at the write end of the pipe + This only makes sense at the write end of the pipe - \sa bytesWritten() for a signal that can be used to determine - when bytes have been written - */ - int bytesToWrite() const; + \sa bytesWritten() for a signal that can be used to determine + when bytes have been written + */ + int bytesToWrite() const; - /** - Read bytes from the pipe. + /** + Read bytes from the pipe. - You can only call this on the read end of the pipe + You can only call this on the read end of the pipe - If the pipe is using secure memory, you should use readSecure() + If the pipe is using secure memory, you should use readSecure() - \param bytes the number of bytes to read (-1 for all - content). - */ - QByteArray read(int bytes = -1); + \param bytes the number of bytes to read (-1 for all + content). + */ + QByteArray read(int bytes = -1); - /** - Write bytes to the pipe. + /** + Write bytes to the pipe. - You can only call this on the write end of the pipe. + You can only call this on the write end of the pipe. - If the pipe is using secure memory, you should use writeSecure(). + If the pipe is using secure memory, you should use writeSecure(). - \param a the array to write to the pipe - */ - void write(const QByteArray &a); + \param a the array to write to the pipe + */ + void write(const QByteArray &a); #ifdef QPIPE_SECURE - /** - Read bytes from the pipe. + /** + Read bytes from the pipe. - You can only call this on the read end of the pipe + You can only call this on the read end of the pipe - If the pipe is using insecure memory, you should use read() + If the pipe is using insecure memory, you should use read() - \param bytes the number of bytes to read (-1 for all - content). - */ - SecureArray readSecure(int bytes = -1); + \param bytes the number of bytes to read (-1 for all + content). + */ + SecureArray readSecure(int bytes = -1); - /** - Write bytes to the pipe. + /** + Write bytes to the pipe. - You can only call this on the write end of the pipe. + You can only call this on the write end of the pipe. - If the pipe is using insecure memory, you should use write(). + If the pipe is using insecure memory, you should use write(). - \param a the array to write to the pipe - */ - void writeSecure(const SecureArray &a); + \param a the array to write to the pipe + */ + void writeSecure(const SecureArray &a); #endif - /** - Returns any unsent bytes queued for writing + /** + Returns any unsent bytes queued for writing - If the pipe is using secure memory, you should use - takeBytesToWriteSecure(). - */ - QByteArray takeBytesToWrite(); + If the pipe is using secure memory, you should use + takeBytesToWriteSecure(). + */ + QByteArray takeBytesToWrite(); #ifdef QPIPE_SECURE - /** - Returns any unsent bytes queued for writing + /** + Returns any unsent bytes queued for writing - If the pipe is using insecure memory, you should use - takeBytesToWrite(). - */ - SecureArray takeBytesToWriteSecure(); + If the pipe is using insecure memory, you should use + takeBytesToWrite(). + */ + SecureArray takeBytesToWriteSecure(); #endif Q_SIGNALS: - /** - Emitted when there are bytes available to be read - from the read end of the pipe. + /** + Emitted when there are bytes available to be read + from the read end of the pipe. - \sa bytesAvailable() - */ - void readyRead(); + \sa bytesAvailable() + */ + void readyRead(); - /** - Emitted when bytes have been written to the - write end of the pipe. + /** + Emitted when bytes have been written to the + write end of the pipe. - \param bytes the number of bytes written - */ - void bytesWritten(int bytes); + \param bytes the number of bytes written + */ + void bytesWritten(int bytes); - /** - Emitted when this end of the pipe is closed as a result of calling - close() + /** + Emitted when this end of the pipe is closed as a result of calling + close() - If this is the write end of the pipe and there is data still - pending to write, this signal will be emitted once all of the data - has been written. + If this is the write end of the pipe and there is data still + pending to write, this signal will be emitted once all of the data + has been written. - To be notified if the other end of the pipe has been closed, see - error(). - */ - void closed(); + To be notified if the other end of the pipe has been closed, see + error(). + */ + void closed(); - /** - Emitted when the pipe encounters an error trying to read or write, - or if the other end of the pipe has been closed + /** + Emitted when the pipe encounters an error trying to read or write, + or if the other end of the pipe has been closed - \param e the reason for error - */ - void error(QCA::QPipeEnd::Error e); + \param e the reason for error + */ + void error(QCA::QPipeEnd::Error e); private: - Q_DISABLE_COPY(QPipeEnd) + Q_DISABLE_COPY(QPipeEnd) - class Private; - friend class Private; - Private *d; + class Private; + friend class Private; + Private *d; }; /** @@ -480,53 +478,59 @@ class QCA_EXPORT QPipe { public: - /** - Standard constructor + /** + Standard constructor - \note You must call create() before using the pipe ends. + \note You must call create() before using the pipe ends. - \param parent the parent object for this object - */ - QPipe(QObject *parent = 0); + \param parent the parent object for this object + */ + QPipe(QObject *parent = 0); - ~QPipe(); + ~QPipe(); - /** - Reset the pipe. + /** + Reset the pipe. - At this point, the readEnd() and writeEnd() calls - will no longer be valid. - */ - void reset(); + At this point, the readEnd() and writeEnd() calls + will no longer be valid. + */ + void reset(); #ifdef QPIPE_SECURE - /** - Create the pipe + /** + Create the pipe - \param secure whether to use secure memory (true) or not (false) - */ - bool create(bool secure = false); + \param secure whether to use secure memory (true) or not (false) + */ + bool create(bool secure = false); #else - /** - Create the pipe - */ - bool create(); + /** + Create the pipe + */ + bool create(); #endif - /** - The read end of the pipe. - */ - QPipeEnd & readEnd() { return i; } - - /** - The write end of the pipe. - */ - QPipeEnd & writeEnd() { return o; } + /** + The read end of the pipe. + */ + QPipeEnd &readEnd() + { + return i; + } + + /** + The write end of the pipe. + */ + QPipeEnd &writeEnd() + { + return o; + } private: - Q_DISABLE_COPY(QPipe) + Q_DISABLE_COPY(QPipe) - QPipeEnd i, o; + QPipeEnd i, o; }; } diff --git a/src/qca_basic.cpp b/src/qca_basic.cpp --- a/src/qca_basic.cpp +++ b/src/qca_basic.cpp @@ -26,7 +26,8 @@ #include #include -namespace QCA { +namespace QCA +{ // from qca_core.cpp QMutex *global_random_mutex(); @@ -39,587 +40,596 @@ static void mergeList(QStringList *a, const QStringList &b) { - foreach(const QString &s, b) - { - if(!a->contains(s)) - a->append(s); - } + foreach (const QString &s, b) { + if (!a->contains(s)) { + a->append(s); + } + } } static QStringList get_hash_types(Provider *p) { - QStringList out; - InfoContext *c = static_cast(getContext("info", p)); - if(!c) - return out; - out = c->supportedHashTypes(); - delete c; - return out; + QStringList out; + InfoContext *c = static_cast(getContext("info", p)); + if (!c) { + return out; + } + out = c->supportedHashTypes(); + delete c; + return out; } static QStringList get_cipher_types(Provider *p) { - QStringList out; - InfoContext *c = static_cast(getContext("info", p)); - if(!c) - return out; - out = c->supportedCipherTypes(); - delete c; - return out; + QStringList out; + InfoContext *c = static_cast(getContext("info", p)); + if (!c) { + return out; + } + out = c->supportedCipherTypes(); + delete c; + return out; } static QStringList get_mac_types(Provider *p) { - QStringList out; - InfoContext *c = static_cast(getContext("info", p)); - if(!c) - return out; - out = c->supportedMACTypes(); - delete c; - return out; -} - -static QStringList get_types(QStringList (*get_func)(Provider *p), const QString &provider) -{ - QStringList out; - if(!provider.isEmpty()) - { - Provider *p = providerForName(provider); - if(p) - out = get_func(p); - } - else - { - ProviderList pl = allProviders(); - foreach(Provider *p, pl) - mergeList(&out, get_func(p)); - } - return out; + QStringList out; + InfoContext *c = static_cast(getContext("info", p)); + if (!c) { + return out; + } + out = c->supportedMACTypes(); + delete c; + return out; +} + +static QStringList get_types(QStringList(*get_func)(Provider *p), const QString &provider) +{ + QStringList out; + if (!provider.isEmpty()) { + Provider *p = providerForName(provider); + if (p) { + out = get_func(p); + } + } else { + ProviderList pl = allProviders(); + foreach (Provider *p, pl) { + mergeList(&out, get_func(p)); + } + } + return out; } static QStringList supportedHashTypes(const QString &provider) { - return get_types(get_hash_types, provider); + return get_types(get_hash_types, provider); } static QStringList supportedCipherTypes(const QString &provider) { - return get_types(get_cipher_types, provider); + return get_types(get_cipher_types, provider); } static QStringList supportedMACTypes(const QString &provider) { - return get_types(get_mac_types, provider); + return get_types(get_mac_types, provider); } //---------------------------------------------------------------------------- // Random //---------------------------------------------------------------------------- Random::Random(const QString &provider) -:Algorithm("random", provider) + : Algorithm("random", provider) { } Random::Random(const Random &from) -:Algorithm(from) + : Algorithm(from) { } Random::~Random() { } -Random & Random::operator=(const Random &from) +Random &Random::operator=(const Random &from) { - Algorithm::operator=(from); - return *this; + Algorithm::operator=(from); + return *this; } uchar Random::nextByte() { - return (uchar)(nextBytes(1)[0]); + return (uchar)(nextBytes(1)[0]); } SecureArray Random::nextBytes(int size) { - return static_cast(context())->nextBytes(size); + return static_cast(context())->nextBytes(size); } uchar Random::randomChar() { - QMutexLocker locker(global_random_mutex()); - return global_random()->nextByte(); + QMutexLocker locker(global_random_mutex()); + return global_random()->nextByte(); } int Random::randomInt() { - QMutexLocker locker(global_random_mutex()); - SecureArray a = global_random()->nextBytes(sizeof(int)); - int x; - memcpy(&x, a.data(), a.size()); - return x; + QMutexLocker locker(global_random_mutex()); + SecureArray a = global_random()->nextBytes(sizeof(int)); + int x; + memcpy(&x, a.data(), a.size()); + return x; } SecureArray Random::randomArray(int size) { - QMutexLocker locker(global_random_mutex()); - return global_random()->nextBytes(size); + QMutexLocker locker(global_random_mutex()); + return global_random()->nextBytes(size); } //---------------------------------------------------------------------------- // Hash //---------------------------------------------------------------------------- Hash::Hash(const QString &type, const QString &provider) -:Algorithm(type, provider) + : Algorithm(type, provider) { } Hash::Hash(const Hash &from) -:Algorithm(from), BufferedComputation(from) + : Algorithm(from), BufferedComputation(from) { } Hash::~Hash() { } -Hash & Hash::operator=(const Hash &from) +Hash &Hash::operator=(const Hash &from) { - Algorithm::operator=(from); - return *this; + Algorithm::operator=(from); + return *this; } QStringList Hash::supportedTypes(const QString &provider) { - return supportedHashTypes(provider); + return supportedHashTypes(provider); } QString Hash::type() const { - // algorithm type is the same as the hash type - return Algorithm::type(); + // algorithm type is the same as the hash type + return Algorithm::type(); } void Hash::clear() { - static_cast(context())->clear(); + static_cast(context())->clear(); } void Hash::update(const MemoryRegion &a) { - static_cast(context())->update(a); + static_cast(context())->update(a); } void Hash::update(const QByteArray &a) { - update(MemoryRegion(a)); + update(MemoryRegion(a)); } void Hash::update(const char *data, int len) { - if(len < 0) - len = qstrlen(data); - if(len == 0) - return; + if (len < 0) { + len = qstrlen(data); + } + if (len == 0) { + return; + } - update(MemoryRegion(QByteArray::fromRawData(data, len))); + update(MemoryRegion(QByteArray::fromRawData(data, len))); } // Reworked from KMD5, from KDE's kdelibs void Hash::update(QIODevice *file) { - char buffer[1024]; - int len; + char buffer[1024]; + int len; - while ((len=file->read(reinterpret_cast(buffer), sizeof(buffer))) > 0) - update(buffer, len); + while ((len = file->read(reinterpret_cast(buffer), sizeof(buffer))) > 0) { + update(buffer, len); + } } MemoryRegion Hash::final() { - return static_cast(context())->final(); + return static_cast(context())->final(); } MemoryRegion Hash::hash(const MemoryRegion &a) { - return process(a); + return process(a); } QString Hash::hashToString(const MemoryRegion &a) { - return arrayToHex(hash(a).toByteArray()); + return arrayToHex(hash(a).toByteArray()); } //---------------------------------------------------------------------------- // Cipher //---------------------------------------------------------------------------- class Cipher::Private { public: - QString type; - Cipher::Mode mode; - Cipher::Padding pad; - Direction dir; - SymmetricKey key; - InitializationVector iv; - AuthTag tag; - - bool ok, done; + QString type; + Cipher::Mode mode; + Cipher::Padding pad; + Direction dir; + SymmetricKey key; + InitializationVector iv; + AuthTag tag; + + bool ok, done; }; Cipher::Cipher(const QString &type, Mode mode, Padding pad, - Direction dir, const SymmetricKey &key, - const InitializationVector &iv, - const QString &provider) -:Algorithm(withAlgorithms(type, mode, pad), provider) + Direction dir, const SymmetricKey &key, + const InitializationVector &iv, + const QString &provider) + : Algorithm(withAlgorithms(type, mode, pad), provider) { - d = new Private; - d->type = type; - d->mode = mode; - d->pad = pad; - if(!key.isEmpty()) - setup(dir, key, iv); + d = new Private; + d->type = type; + d->mode = mode; + d->pad = pad; + if (!key.isEmpty()) { + setup(dir, key, iv); + } } Cipher::Cipher(const QString &type, Cipher::Mode mode, Cipher::Padding pad, Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag, const QString &provider) - : Algorithm(withAlgorithms(type, mode, pad), provider) + : Algorithm(withAlgorithms(type, mode, pad), provider) { - d = new Private; - d->type = type; - d->mode = mode; - d->pad = pad; - d->tag = tag; - if(!key.isEmpty()) - setup(dir, key, iv, tag); + d = new Private; + d->type = type; + d->mode = mode; + d->pad = pad; + d->tag = tag; + if (!key.isEmpty()) { + setup(dir, key, iv, tag); + } } - Cipher::Cipher(const Cipher &from) -:Algorithm(from), Filter(from) + : Algorithm(from), Filter(from) { - d = new Private(*from.d); + d = new Private(*from.d); } Cipher::~Cipher() { - delete d; + delete d; } -Cipher & Cipher::operator=(const Cipher &from) +Cipher &Cipher::operator=(const Cipher &from) { - Algorithm::operator=(from); - *d = *from.d; - return *this; + Algorithm::operator=(from); + *d = *from.d; + return *this; } QStringList Cipher::supportedTypes(const QString &provider) { - return supportedCipherTypes(provider); + return supportedCipherTypes(provider); } QString Cipher::type() const { - return d->type; + return d->type; } Cipher::Mode Cipher::mode() const { - return d->mode; + return d->mode; } Cipher::Padding Cipher::padding() const { - return d->pad; + return d->pad; } Direction Cipher::direction() const { - return d->dir; + return d->dir; } KeyLength Cipher::keyLength() const { - return static_cast(context())->keyLength(); + return static_cast(context())->keyLength(); } bool Cipher::validKeyLength(int n) const { - KeyLength len = keyLength(); - return ((n >= len.minimum()) && (n <= len.maximum()) && (n % len.multiple() == 0)); + KeyLength len = keyLength(); + return ((n >= len.minimum()) && (n <= len.maximum()) && (n % len.multiple() == 0)); } int Cipher::blockSize() const { - return static_cast(context())->blockSize(); + return static_cast(context())->blockSize(); } AuthTag Cipher::tag() const { - return static_cast(context())->tag(); + return static_cast(context())->tag(); } void Cipher::clear() { - d->done = false; - static_cast(context())->setup(d->dir, d->key, d->iv, d->tag); + d->done = false; + static_cast(context())->setup(d->dir, d->key, d->iv, d->tag); } MemoryRegion Cipher::update(const MemoryRegion &a) { - SecureArray out; - if(d->done) - return out; - d->ok = static_cast(context())->update(a, &out); - return out; + SecureArray out; + if (d->done) { + return out; + } + d->ok = static_cast(context())->update(a, &out); + return out; } MemoryRegion Cipher::final() { - SecureArray out; - if(d->done) - return out; - d->done = true; - d->ok = static_cast(context())->final(&out); - return out; + SecureArray out; + if (d->done) { + return out; + } + d->done = true; + d->ok = static_cast(context())->final(&out); + return out; } bool Cipher::ok() const { - return d->ok; + return d->ok; } void Cipher::setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv) { - setup(dir, key, iv, AuthTag()); + setup(dir, key, iv, AuthTag()); } void Cipher::setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv, const AuthTag &tag) { - d->dir = dir; - d->key = key; - d->iv = iv; - d->tag = tag; - clear(); + d->dir = dir; + d->key = key; + d->iv = iv; + d->tag = tag; + clear(); } QString Cipher::withAlgorithms(const QString &cipherType, Mode modeType, Padding paddingType) { - QString mode; - switch(modeType) { - case CBC: - mode = "cbc"; - break; - case CFB: - mode = "cfb"; - break; - case OFB: - mode = "ofb"; - break; - case ECB: - mode = "ecb"; - break; - case CTR: - mode = "ctr"; - break; - case GCM: - mode = "gcm"; - break; - case CCM: - mode = "ccm"; - break; - default: - Q_ASSERT(0); - } - - // do the default - if(paddingType == DefaultPadding) - { - // logic from Botan - if(modeType == CBC) - paddingType = PKCS7; - else - paddingType = NoPadding; - } - - QString pad; - if(paddingType == NoPadding) - pad = ""; - else - pad = "pkcs7"; - - QString result = cipherType + '-' + mode; - if(!pad.isEmpty()) - result += QString("-") + pad; - - return result; + QString mode; + switch (modeType) { + case CBC: + mode = "cbc"; + break; + case CFB: + mode = "cfb"; + break; + case OFB: + mode = "ofb"; + break; + case ECB: + mode = "ecb"; + break; + case CTR: + mode = "ctr"; + break; + case GCM: + mode = "gcm"; + break; + case CCM: + mode = "ccm"; + break; + default: + Q_ASSERT(0); + } + + // do the default + if (paddingType == DefaultPadding) { + // logic from Botan + if (modeType == CBC) { + paddingType = PKCS7; + } else { + paddingType = NoPadding; + } + } + + QString pad; + if (paddingType == NoPadding) { + pad = ""; + } else { + pad = "pkcs7"; + } + + QString result = cipherType + '-' + mode; + if (!pad.isEmpty()) { + result += QString("-") + pad; + } + + return result; } //---------------------------------------------------------------------------- // MessageAuthenticationCode //---------------------------------------------------------------------------- class MessageAuthenticationCode::Private { public: - SymmetricKey key; + SymmetricKey key; - bool done; - MemoryRegion buf; + bool done; + MemoryRegion buf; }; - MessageAuthenticationCode::MessageAuthenticationCode(const QString &type, - const SymmetricKey &key, - const QString &provider) -:Algorithm(type, provider) + const SymmetricKey &key, + const QString &provider) + : Algorithm(type, provider) { - d = new Private; - setup(key); + d = new Private; + setup(key); } MessageAuthenticationCode::MessageAuthenticationCode(const MessageAuthenticationCode &from) -:Algorithm(from), BufferedComputation(from) + : Algorithm(from), BufferedComputation(from) { - d = new Private(*from.d); + d = new Private(*from.d); } MessageAuthenticationCode::~MessageAuthenticationCode() { - delete d; + delete d; } -MessageAuthenticationCode & MessageAuthenticationCode::operator=(const MessageAuthenticationCode &from) +MessageAuthenticationCode &MessageAuthenticationCode::operator=(const MessageAuthenticationCode &from) { - Algorithm::operator=(from); - *d = *from.d; - return *this; + Algorithm::operator=(from); + *d = *from.d; + return *this; } QStringList MessageAuthenticationCode::supportedTypes(const QString &provider) { - return supportedMACTypes(provider); + return supportedMACTypes(provider); } QString MessageAuthenticationCode::type() const { - // algorithm type is the same as the mac type - return Algorithm::type(); + // algorithm type is the same as the mac type + return Algorithm::type(); } KeyLength MessageAuthenticationCode::keyLength() const { - return static_cast(context())->keyLength(); + return static_cast(context())->keyLength(); } bool MessageAuthenticationCode::validKeyLength(int n) const { - KeyLength len = keyLength(); - return ((n >= len.minimum()) && (n <= len.maximum()) && (n % len.multiple() == 0)); + KeyLength len = keyLength(); + return ((n >= len.minimum()) && (n <= len.maximum()) && (n % len.multiple() == 0)); } void MessageAuthenticationCode::clear() { - d->done = false; - static_cast(context())->setup(d->key); + d->done = false; + static_cast(context())->setup(d->key); } void MessageAuthenticationCode::update(const MemoryRegion &a) { - if(d->done) - return; - static_cast(context())->update(a); + if (d->done) { + return; + } + static_cast(context())->update(a); } MemoryRegion MessageAuthenticationCode::final() { - if(!d->done) - { - d->done = true; - static_cast(context())->final(&d->buf); - } - return d->buf; + if (!d->done) { + d->done = true; + static_cast(context())->final(&d->buf); + } + return d->buf; } void MessageAuthenticationCode::setup(const SymmetricKey &key) { - d->key = key; - clear(); + d->key = key; + clear(); } //---------------------------------------------------------------------------- // Key Derivation Function //---------------------------------------------------------------------------- KeyDerivationFunction::KeyDerivationFunction(const QString &type, const QString &provider) -:Algorithm(type, provider) + : Algorithm(type, provider) { } KeyDerivationFunction::KeyDerivationFunction(const KeyDerivationFunction &from) -:Algorithm(from) + : Algorithm(from) { } KeyDerivationFunction::~KeyDerivationFunction() { } -KeyDerivationFunction & KeyDerivationFunction::operator=(const KeyDerivationFunction &from) +KeyDerivationFunction &KeyDerivationFunction::operator=(const KeyDerivationFunction &from) { - Algorithm::operator=(from); - return *this; + Algorithm::operator=(from); + return *this; } SymmetricKey KeyDerivationFunction::makeKey(const SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount) { - return static_cast(context())->makeKey(secret, salt, keyLength, iterationCount); + return static_cast(context())->makeKey(secret, salt, keyLength, iterationCount); } SymmetricKey KeyDerivationFunction::makeKey(const SecureArray &secret, - const InitializationVector &salt, - unsigned int keyLength, - int msecInterval, - unsigned int *iterationCount) + const InitializationVector &salt, + unsigned int keyLength, + int msecInterval, + unsigned int *iterationCount) { - return static_cast(context())->makeKey(secret, - salt, - keyLength, - msecInterval, - iterationCount); + return static_cast(context())->makeKey(secret, + salt, + keyLength, + msecInterval, + iterationCount); } QString KeyDerivationFunction::withAlgorithm(const QString &kdfType, const QString &algType) { - return (kdfType + '(' + algType + ')'); + return (kdfType + '(' + algType + ')'); } //---------------------------------------------------------------------------- // HKDF //---------------------------------------------------------------------------- HKDF::HKDF(const QString &algorithm, const QString &provider) -: Algorithm(QStringLiteral("hkdf(") + algorithm + ')', provider) + : Algorithm(QStringLiteral("hkdf(") + algorithm + ')', provider) { } HKDF::HKDF(const HKDF &from) -: Algorithm(from) + : Algorithm(from) { } HKDF::~HKDF() { } -HKDF & HKDF::operator=(const HKDF &from) +HKDF &HKDF::operator=(const HKDF &from) { - Algorithm::operator=(from); - return *this; + Algorithm::operator=(from); + return *this; } SymmetricKey HKDF::makeKey(const SecureArray &secret, const InitializationVector &salt, const InitializationVector &info, unsigned int keyLength) { - return static_cast(context())->makeKey(secret, - salt, - info, - keyLength); + return static_cast(context())->makeKey(secret, + salt, + info, + keyLength); } } diff --git a/src/qca_cert.cpp b/src/qca_cert.cpp --- a/src/qca_cert.cpp +++ b/src/qca_cert.cpp @@ -30,7 +30,8 @@ #include -namespace QCA { +namespace QCA +{ Provider::Context *getContext(const QString &type, const QString &provider); Provider::Context *getContext(const QString &type, Provider *p); @@ -48,115 +49,115 @@ // last 3 arguments must be valid, and chain must be empty static bool get_pkcs12_der(const QByteArray &der, const QString &fileName, void *ptr, const SecureArray &passphrase, ConvertResult *result, const QString &provider, QString *name, CertificateChain *chain, PrivateKey *key) { - QString _name; - QList list; - PKeyContext *kc = 0; - - PKCS12Context *pix = static_cast(getContext("pkcs12", provider)); - ConvertResult r = pix->fromPKCS12(der, passphrase, &_name, &list, &kc); - - // error converting without passphrase? maybe a passphrase is needed - if(use_asker_fallback(r) && passphrase.isEmpty()) - { - SecureArray pass; - if(ask_passphrase(fileName, ptr, &pass)) - r = pix->fromPKCS12(der, pass, &_name, &list, &kc); - } - delete pix; - - if(result) - *result = r; - - if(r == ConvertGood) - { - *name = _name; - for(int n = 0; n < list.count(); ++n) - { - Certificate cert; - cert.change(list[n]); - chain->append(cert); - } - key->change(kc); - return true; - } - return false; + QString _name; + QList list; + PKeyContext *kc = 0; + + PKCS12Context *pix = static_cast(getContext("pkcs12", provider)); + ConvertResult r = pix->fromPKCS12(der, passphrase, &_name, &list, &kc); + + // error converting without passphrase? maybe a passphrase is needed + if (use_asker_fallback(r) && passphrase.isEmpty()) { + SecureArray pass; + if (ask_passphrase(fileName, ptr, &pass)) { + r = pix->fromPKCS12(der, pass, &_name, &list, &kc); + } + } + delete pix; + + if (result) { + *result = r; + } + + if (r == ConvertGood) { + *name = _name; + for (int n = 0; n < list.count(); ++n) { + Certificate cert; + cert.change(list[n]); + chain->append(cert); + } + key->change(kc); + return true; + } + return false; } static CertificateInfo orderedToMap(const CertificateInfoOrdered &info) { - CertificateInfo out; + CertificateInfo out; - // first, do all but EmailLegacy - for(int n = 0; n < info.count(); ++n) - { - const CertificateInfoPair &i = info[n]; - if(i.type().known() != EmailLegacy) - out.insert(i.type(), i.value()); - } + // first, do all but EmailLegacy + for (int n = 0; n < info.count(); ++n) { + const CertificateInfoPair &i = info[n]; + if (i.type().known() != EmailLegacy) { + out.insert(i.type(), i.value()); + } + } - // lastly, apply EmailLegacy - for(int n = 0; n < info.count(); ++n) - { - const CertificateInfoPair &i = info[n]; - if(i.type().known() == EmailLegacy) - { - // de-dup - QList emails = out.values(Email); - if(!emails.contains(i.value())) - out.insert(Email, i.value()); - } - } + // lastly, apply EmailLegacy + for (int n = 0; n < info.count(); ++n) { + const CertificateInfoPair &i = info[n]; + if (i.type().known() == EmailLegacy) { + // de-dup + QList emails = out.values(Email); + if (!emails.contains(i.value())) { + out.insert(Email, i.value()); + } + } + } - return out; + return out; } static void moveMapValues(CertificateInfo *from, CertificateInfoOrdered *to, const CertificateInfoType &type) { - QList values = from->values(type); - from->remove(type); + QList values = from->values(type); + from->remove(type); - // multimap values are stored in reverse. we'll insert backwards in - // order to right them. - for(int n = values.count() - 1; n >= 0; --n) - to->append(CertificateInfoPair(type, values[n])); + // multimap values are stored in reverse. we'll insert backwards in + // order to right them. + for (int n = values.count() - 1; n >= 0; --n) { + to->append(CertificateInfoPair(type, values[n])); + } } static CertificateInfoOrdered mapToOrdered(const CertificateInfo &info) { - CertificateInfo in = info; - CertificateInfoOrdered out; + CertificateInfo in = info; + CertificateInfoOrdered out; - // have a specific order for some types - moveMapValues(&in, &out, CommonName); - moveMapValues(&in, &out, Country); - moveMapValues(&in, &out, Locality); - moveMapValues(&in, &out, State); - moveMapValues(&in, &out, Organization); - moveMapValues(&in, &out, OrganizationalUnit); - moveMapValues(&in, &out, Email); - moveMapValues(&in, &out, URI); - moveMapValues(&in, &out, DNS); - moveMapValues(&in, &out, IPAddress); - moveMapValues(&in, &out, XMPP); + // have a specific order for some types + moveMapValues(&in, &out, CommonName); + moveMapValues(&in, &out, Country); + moveMapValues(&in, &out, Locality); + moveMapValues(&in, &out, State); + moveMapValues(&in, &out, Organization); + moveMapValues(&in, &out, OrganizationalUnit); + moveMapValues(&in, &out, Email); + moveMapValues(&in, &out, URI); + moveMapValues(&in, &out, DNS); + moveMapValues(&in, &out, IPAddress); + moveMapValues(&in, &out, XMPP); - // get remaining types - QList typesLeft = in.keys(); + // get remaining types + QList typesLeft = in.keys(); - // dedup - QList types; - for(int n = 0; n < typesLeft.count(); ++n) - { - if(!types.contains(typesLeft[n])) - types += typesLeft[n]; - } + // dedup + QList types; + for (int n = 0; n < typesLeft.count(); ++n) { + if (!types.contains(typesLeft[n])) { + types += typesLeft[n]; + } + } - // insert the rest of the types in the order we got them (map order) - for(int n = 0; n < types.count(); ++n) - moveMapValues(&in, &out, types[n]); + // insert the rest of the types in the order we got them (map order) + for (int n = 0; n < types.count(); ++n) { + moveMapValues(&in, &out, types[n]); + } - Q_ASSERT(in.isEmpty()); + Q_ASSERT(in.isEmpty()); - return out; + return out; } //---------------------------------------------------------------------------- @@ -199,997 +200,982 @@ static QString knownToId(CertificateInfoTypeKnown k) { - const char *out = 0; - switch(k) - { - case CommonName: out = CommonName_id; break; - case Email: out = Email_id; break; - case EmailLegacy: out = EmailLegacy_id; break; - case Organization: out = Organization_id; break; - case OrganizationalUnit: out = OrganizationalUnit_id; break; - case Locality: out = Locality_id; break; - case IncorporationLocality: out = IncorporationLocality_id; break; - case State: out = State_id; break; - case IncorporationState: out = IncorporationState_id; break; - case Country: out = Country_id; break; - case IncorporationCountry: out = IncorporationCountry_id; break; - case URI: out = URI_id; break; - case DNS: out = DNS_id; break; - case IPAddress: out = IPAddress_id; break; - case XMPP: out = XMPP_id; break; - } - Q_ASSERT(out); - if(!out) - abort(); - return QString(out); + const char *out = 0; + switch (k) { + case CommonName: out = CommonName_id; break; + case Email: out = Email_id; break; + case EmailLegacy: out = EmailLegacy_id; break; + case Organization: out = Organization_id; break; + case OrganizationalUnit: out = OrganizationalUnit_id; break; + case Locality: out = Locality_id; break; + case IncorporationLocality: out = IncorporationLocality_id; break; + case State: out = State_id; break; + case IncorporationState: out = IncorporationState_id; break; + case Country: out = Country_id; break; + case IncorporationCountry: out = IncorporationCountry_id; break; + case URI: out = URI_id; break; + case DNS: out = DNS_id; break; + case IPAddress: out = IPAddress_id; break; + case XMPP: out = XMPP_id; break; + } + Q_ASSERT(out); + if (!out) { + abort(); + } + return QString(out); } static int idToKnown(const QString &id) { - if(id == CommonName_id) - return CommonName; - else if(id == Email_id) - return Email; - else if(id == EmailLegacy_id) - return EmailLegacy; - else if(id == Organization_id) - return Organization; - else if(id == OrganizationalUnit_id) - return OrganizationalUnit; - else if(id == Locality_id) - return Locality; - else if(id == IncorporationLocality_id) - return IncorporationLocality; - else if(id == State_id) - return State; - else if(id == IncorporationState_id) - return IncorporationState; - else if(id == Country_id) - return Country; - else if(id == IncorporationCountry_id) - return IncorporationCountry; - else if(id == URI_id) - return URI; - else if(id == DNS_id) - return DNS; - else if(id == IPAddress_id) - return IPAddress; - else if(id == XMPP_id) - return XMPP; - else - return -1; + if (id == CommonName_id) { + return CommonName; + } else if (id == Email_id) { + return Email; + } else if (id == EmailLegacy_id) { + return EmailLegacy; + } else if (id == Organization_id) { + return Organization; + } else if (id == OrganizationalUnit_id) { + return OrganizationalUnit; + } else if (id == Locality_id) { + return Locality; + } else if (id == IncorporationLocality_id) { + return IncorporationLocality; + } else if (id == State_id) { + return State; + } else if (id == IncorporationState_id) { + return IncorporationState; + } else if (id == Country_id) { + return Country; + } else if (id == IncorporationCountry_id) { + return IncorporationCountry; + } else if (id == URI_id) { + return URI; + } else if (id == DNS_id) { + return DNS; + } else if (id == IPAddress_id) { + return IPAddress; + } else if (id == XMPP_id) { + return XMPP; + } else { + return -1; + } } static CertificateInfoType::Section knownToSection(CertificateInfoTypeKnown k) { - switch(k) - { - case CommonName: - case EmailLegacy: - case Organization: - case OrganizationalUnit: - case Locality: - case IncorporationLocality: - case State: - case IncorporationState: - case Country: - case IncorporationCountry: - return CertificateInfoType::DN; - default: - break; - } - return CertificateInfoType::AlternativeName; + switch (k) { + case CommonName: + case EmailLegacy: + case Organization: + case OrganizationalUnit: + case Locality: + case IncorporationLocality: + case State: + case IncorporationState: + case Country: + case IncorporationCountry: + return CertificateInfoType::DN; + default: + break; + } + return CertificateInfoType::AlternativeName; } static const char *knownToShortName(CertificateInfoTypeKnown k) { - switch(k) - { - case CommonName: return "CN"; - case Locality: return "L"; - case State: return "ST"; - case Organization: return "O"; - case OrganizationalUnit: return "OU"; - case Country: return "C"; - case EmailLegacy: return "emailAddress"; - default: break; - } - return 0; + switch (k) { + case CommonName: return "CN"; + case Locality: return "L"; + case State: return "ST"; + case Organization: return "O"; + case OrganizationalUnit: return "OU"; + case Country: return "C"; + case EmailLegacy: return "emailAddress"; + default: break; + } + return 0; } static QString constraintKnownToId(ConstraintTypeKnown k) { - const char *out = 0; - switch(k) - { - case DigitalSignature: out = DigitalSignature_id; break; - case NonRepudiation: out = NonRepudiation_id; break; - case KeyEncipherment: out = KeyEncipherment_id; break; - case DataEncipherment: out = DataEncipherment_id; break; - case KeyAgreement: out = KeyAgreement_id; break; - case KeyCertificateSign: out = KeyCertificateSign_id; break; - case CRLSign: out = CRLSign_id; break; - case EncipherOnly: out = EncipherOnly_id; break; - case DecipherOnly: out = DecipherOnly_id; break; - case ServerAuth: out = ServerAuth_id; break; - case ClientAuth: out = ClientAuth_id; break; - case CodeSigning: out = CodeSigning_id; break; - case EmailProtection: out = EmailProtection_id; break; - case IPSecEndSystem: out = IPSecEndSystem_id; break; - case IPSecTunnel: out = IPSecTunnel_id; break; - case IPSecUser: out = IPSecUser_id; break; - case TimeStamping: out = TimeStamping_id; break; - case OCSPSigning: out = OCSPSigning_id; break; - } - Q_ASSERT(out); - if(!out) - abort(); - return QString(out); + const char *out = 0; + switch (k) { + case DigitalSignature: out = DigitalSignature_id; break; + case NonRepudiation: out = NonRepudiation_id; break; + case KeyEncipherment: out = KeyEncipherment_id; break; + case DataEncipherment: out = DataEncipherment_id; break; + case KeyAgreement: out = KeyAgreement_id; break; + case KeyCertificateSign: out = KeyCertificateSign_id; break; + case CRLSign: out = CRLSign_id; break; + case EncipherOnly: out = EncipherOnly_id; break; + case DecipherOnly: out = DecipherOnly_id; break; + case ServerAuth: out = ServerAuth_id; break; + case ClientAuth: out = ClientAuth_id; break; + case CodeSigning: out = CodeSigning_id; break; + case EmailProtection: out = EmailProtection_id; break; + case IPSecEndSystem: out = IPSecEndSystem_id; break; + case IPSecTunnel: out = IPSecTunnel_id; break; + case IPSecUser: out = IPSecUser_id; break; + case TimeStamping: out = TimeStamping_id; break; + case OCSPSigning: out = OCSPSigning_id; break; + } + Q_ASSERT(out); + if (!out) { + abort(); + } + return QString(out); } static int constraintIdToKnown(const QString &id) { - if(id == DigitalSignature_id) - return DigitalSignature; - else if(id == NonRepudiation_id) - return NonRepudiation; - else if(id == KeyEncipherment_id) - return KeyEncipherment; - else if(id == DataEncipherment_id) - return DataEncipherment; - else if(id == KeyAgreement_id) - return KeyAgreement; - else if(id == KeyCertificateSign_id) - return KeyCertificateSign; - else if(id == CRLSign_id) - return CRLSign; - else if(id == EncipherOnly_id) - return EncipherOnly; - else if(id == DecipherOnly_id) - return DecipherOnly; - else if(id == ServerAuth_id) - return ServerAuth; - else if(id == ClientAuth_id) - return ClientAuth; - else if(id == CodeSigning_id) - return CodeSigning; - else if(id == EmailProtection_id) - return EmailProtection; - else if(id == IPSecEndSystem_id) - return IPSecEndSystem; - else if(id == IPSecTunnel_id) - return IPSecTunnel; - else if(id == IPSecUser_id) - return IPSecUser; - else if(id == TimeStamping_id) - return TimeStamping; - else if(id == OCSPSigning_id) - return OCSPSigning; - else - return -1; + if (id == DigitalSignature_id) { + return DigitalSignature; + } else if (id == NonRepudiation_id) { + return NonRepudiation; + } else if (id == KeyEncipherment_id) { + return KeyEncipherment; + } else if (id == DataEncipherment_id) { + return DataEncipherment; + } else if (id == KeyAgreement_id) { + return KeyAgreement; + } else if (id == KeyCertificateSign_id) { + return KeyCertificateSign; + } else if (id == CRLSign_id) { + return CRLSign; + } else if (id == EncipherOnly_id) { + return EncipherOnly; + } else if (id == DecipherOnly_id) { + return DecipherOnly; + } else if (id == ServerAuth_id) { + return ServerAuth; + } else if (id == ClientAuth_id) { + return ClientAuth; + } else if (id == CodeSigning_id) { + return CodeSigning; + } else if (id == EmailProtection_id) { + return EmailProtection; + } else if (id == IPSecEndSystem_id) { + return IPSecEndSystem; + } else if (id == IPSecTunnel_id) { + return IPSecTunnel; + } else if (id == IPSecUser_id) { + return IPSecUser; + } else if (id == TimeStamping_id) { + return TimeStamping; + } else if (id == OCSPSigning_id) { + return OCSPSigning; + } else { + return -1; + } } static ConstraintType::Section constraintKnownToSection(ConstraintTypeKnown k) { - switch(k) - { - case DigitalSignature: - case NonRepudiation: - case KeyEncipherment: - case DataEncipherment: - case KeyAgreement: - case KeyCertificateSign: - case CRLSign: - case EncipherOnly: - case DecipherOnly: - return ConstraintType::KeyUsage; - default: - break; - } - return ConstraintType::ExtendedKeyUsage; + switch (k) { + case DigitalSignature: + case NonRepudiation: + case KeyEncipherment: + case DataEncipherment: + case KeyAgreement: + case KeyCertificateSign: + case CRLSign: + case EncipherOnly: + case DecipherOnly: + return ConstraintType::KeyUsage; + default: + break; + } + return ConstraintType::ExtendedKeyUsage; } static QString dnLabel(const CertificateInfoType &type) { - const char *str = knownToShortName(type.known()); - if(str) - return str; + const char *str = knownToShortName(type.known()); + if (str) { + return str; + } - QString id = type.id(); - // is it an oid? - if(id[0].isDigit()) - return QString("OID.") + id; + QString id = type.id(); + // is it an oid? + if (id[0].isDigit()) { + return QString("OID.") + id; + } - return QString("qca.") + id; + return QString("qca.") + id; } QString orderedToDNString(const CertificateInfoOrdered &in) { - QStringList parts; - foreach(const CertificateInfoPair &i, in) - { - if(i.type().section() != CertificateInfoType::DN) - continue; + QStringList parts; + foreach (const CertificateInfoPair &i, in) { + if (i.type().section() != CertificateInfoType::DN) { + continue; + } - QString name = dnLabel(i.type()); - parts += name + '=' + i.value(); - } - return parts.join(", "); + QString name = dnLabel(i.type()); + parts += name + '=' + i.value(); + } + return parts.join(", "); } CertificateInfoOrdered orderedDNOnly(const CertificateInfoOrdered &in) { - CertificateInfoOrdered out; - for(int n = 0; n < in.count(); ++n) - { - if(in[n].type().section() == CertificateInfoType::DN) - out += in[n]; - } - return out; + CertificateInfoOrdered out; + for (int n = 0; n < in.count(); ++n) { + if (in[n].type().section() == CertificateInfoType::DN) { + out += in[n]; + } + } + return out; } static QString baseCertName(const CertificateInfo &info) { - QString str = info.value(CommonName); - if(str.isEmpty()) - { - str = info.value(Organization); - if(str.isEmpty()) - str = "Unnamed"; - } - return str; + QString str = info.value(CommonName); + if (str.isEmpty()) { + str = info.value(Organization); + if (str.isEmpty()) { + str = "Unnamed"; + } + } + return str; } static QList findSameName(const QString &name, const QStringList &list) { - QList out; - for(int n = 0; n < list.count(); ++n) - { - if(list[n] == name) - out += n; - } - return out; + QList out; + for (int n = 0; n < list.count(); ++n) { + if (list[n] == name) { + out += n; + } + } + return out; } static QString uniqueSubjectValue(const CertificateInfoType &type, const QList items, const QList &certs, int i) { - QStringList vals = certs[items[i]].subjectInfo().values(type); - if(!vals.isEmpty()) - { - foreach(int n, items) - { - if(n == items[i]) - continue; + QStringList vals = certs[items[i]].subjectInfo().values(type); + if (!vals.isEmpty()) { + foreach (int n, items) { + if (n == items[i]) { + continue; + } - QStringList other_vals = certs[n].subjectInfo().values(type); - for(int k = 0; k < vals.count(); ++k) - { - if(other_vals.contains(vals[k])) - { - vals.removeAt(k); - break; - } - } + QStringList other_vals = certs[n].subjectInfo().values(type); + for (int k = 0; k < vals.count(); ++k) { + if (other_vals.contains(vals[k])) { + vals.removeAt(k); + break; + } + } - if(vals.isEmpty()) - break; - } + if (vals.isEmpty()) { + break; + } + } - if(!vals.isEmpty()) - return vals[0]; - } + if (!vals.isEmpty()) { + return vals[0]; + } + } - return QString(); + return QString(); } static QString uniqueIssuerName(const QList items, const QList &certs, int i) { - QString val = baseCertName(certs[items[i]].issuerInfo()); + QString val = baseCertName(certs[items[i]].issuerInfo()); - bool found = false; - foreach(int n, items) - { - if(n == items[i]) - continue; + bool found = false; + foreach (int n, items) { + if (n == items[i]) { + continue; + } - QString other_val = baseCertName(certs[n].issuerInfo()); - if(other_val == val) - { - found = true; - break; - } - } + QString other_val = baseCertName(certs[n].issuerInfo()); + if (other_val == val) { + found = true; + break; + } + } - if(!found) - return val; + if (!found) { + return val; + } - return QString(); + return QString(); } static const char *constraintToString(const ConstraintType &type) { - switch(type.known()) - { - case DigitalSignature: return "DigitalSignature"; - case NonRepudiation: return "NonRepudiation"; - case KeyEncipherment: return "KeyEncipherment"; - case DataEncipherment: return "DataEncipherment"; - case KeyAgreement: return "KeyAgreement"; - case KeyCertificateSign: return "KeyCertificateSign"; - case CRLSign: return "CRLSign"; - case EncipherOnly: return "EncipherOnly"; - case DecipherOnly: return "DecipherOnly"; - case ServerAuth: return "ServerAuth"; - case ClientAuth: return "ClientAuth"; - case CodeSigning: return "CodeSigning"; - case EmailProtection: return "EmailProtection"; - case IPSecEndSystem: return "IPSecEndSystem"; - case IPSecTunnel: return "IPSecTunnel"; - case IPSecUser: return "IPSecUser"; - case TimeStamping: return "TimeStamping"; - case OCSPSigning: return "OCSPSigning"; - } - return 0; + switch (type.known()) { + case DigitalSignature: return "DigitalSignature"; + case NonRepudiation: return "NonRepudiation"; + case KeyEncipherment: return "KeyEncipherment"; + case DataEncipherment: return "DataEncipherment"; + case KeyAgreement: return "KeyAgreement"; + case KeyCertificateSign: return "KeyCertificateSign"; + case CRLSign: return "CRLSign"; + case EncipherOnly: return "EncipherOnly"; + case DecipherOnly: return "DecipherOnly"; + case ServerAuth: return "ServerAuth"; + case ClientAuth: return "ClientAuth"; + case CodeSigning: return "CodeSigning"; + case EmailProtection: return "EmailProtection"; + case IPSecEndSystem: return "IPSecEndSystem"; + case IPSecTunnel: return "IPSecTunnel"; + case IPSecUser: return "IPSecUser"; + case TimeStamping: return "TimeStamping"; + case OCSPSigning: return "OCSPSigning"; + } + return 0; } static QString uniqueConstraintValue(const ConstraintType &type, const QList items, const QList &certs, int i) { - ConstraintType val = type; - if(certs[items[i]].constraints().contains(type)) - { - bool found = false; - foreach(int n, items) - { - if(n == items[i]) - continue; + ConstraintType val = type; + if (certs[items[i]].constraints().contains(type)) { + bool found = false; + foreach (int n, items) { + if (n == items[i]) { + continue; + } - Constraints other_vals = certs[n].constraints(); - if(other_vals.contains(val)) - { - found = true; - break; - } - } + Constraints other_vals = certs[n].constraints(); + if (other_vals.contains(val)) { + found = true; + break; + } + } - if(!found) - return QString(constraintToString(val)); - } + if (!found) { + return QString(constraintToString(val)); + } + } - return QString(); + return QString(); } static QString makeUniqueName(const QList &items, const QStringList &list, const QList &certs, int i) { - QString str, name; - - // different organization? - str = uniqueSubjectValue(Organization, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" of ") + str; - goto end; - } - - // different organizational unit? - str = uniqueSubjectValue(OrganizationalUnit, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" of ") + str; - goto end; - } - - // different email address? - str = uniqueSubjectValue(Email, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" <") + str + '>'; - goto end; - } - - // different xmpp addresses? - str = uniqueSubjectValue(XMPP, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" '; - goto end; - } - - // different issuers? - str = uniqueIssuerName(items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" by ") + str; - goto end; - } - - // different usages? - - // DigitalSignature - str = uniqueConstraintValue(DigitalSignature, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" for ") + str; - goto end; - } - - // ClientAuth - str = uniqueConstraintValue(ClientAuth, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" for ") + str; - goto end; - } - - // EmailProtection - str = uniqueConstraintValue(EmailProtection, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" for ") + str; - goto end; - } - - // DataEncipherment - str = uniqueConstraintValue(DataEncipherment, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" for ") + str; - goto end; - } - - // EncipherOnly - str = uniqueConstraintValue(EncipherOnly, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" for ") + str; - goto end; - } - - // DecipherOnly - str = uniqueConstraintValue(DecipherOnly, items, certs, i); - if(!str.isEmpty()) - { - name = list[items[i]] + QString(" for ") + str; - goto end; - } - - // if there's nothing easily unique, then do a DN string - name = certs[items[i]].subjectInfoOrdered().toString(); + QString str, name; + + // different organization? + str = uniqueSubjectValue(Organization, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" of ") + str; + goto end; + } + + // different organizational unit? + str = uniqueSubjectValue(OrganizationalUnit, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" of ") + str; + goto end; + } + + // different email address? + str = uniqueSubjectValue(Email, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" <") + str + '>'; + goto end; + } + + // different xmpp addresses? + str = uniqueSubjectValue(XMPP, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" '; + goto end; + } + + // different issuers? + str = uniqueIssuerName(items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" by ") + str; + goto end; + } + + // different usages? + + // DigitalSignature + str = uniqueConstraintValue(DigitalSignature, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" for ") + str; + goto end; + } + + // ClientAuth + str = uniqueConstraintValue(ClientAuth, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" for ") + str; + goto end; + } + + // EmailProtection + str = uniqueConstraintValue(EmailProtection, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" for ") + str; + goto end; + } + + // DataEncipherment + str = uniqueConstraintValue(DataEncipherment, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" for ") + str; + goto end; + } + + // EncipherOnly + str = uniqueConstraintValue(EncipherOnly, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" for ") + str; + goto end; + } + + // DecipherOnly + str = uniqueConstraintValue(DecipherOnly, items, certs, i); + if (!str.isEmpty()) { + name = list[items[i]] + QString(" for ") + str; + goto end; + } + + // if there's nothing easily unique, then do a DN string + name = certs[items[i]].subjectInfoOrdered().toString(); end: - return name; + return name; } QStringList makeFriendlyNames(const QList &list) { - QStringList names; - - // give a base name to all certs first - foreach(const Certificate &cert, list) - names += baseCertName(cert.subjectInfo()); - - // come up with a collision list - QList< QList > itemCollisions; - foreach(const QString &name, names) - { - // anyone else using this name? - QList items = findSameName(name, names); - if(items.count() > 1) - { - // don't save duplicate collisions - bool haveAlready = false; - foreach(const QList &other, itemCollisions) - { - foreach(int n, items) - { - if(other.contains(n)) - { - haveAlready = true; - break; - } - } - - if(haveAlready) - break; - } - - if(haveAlready) - continue; - - itemCollisions += items; - } - } - - // resolve collisions by providing extra details - foreach(const QList &items, itemCollisions) - { - //printf("%d items are using [%s]\n", items.count(), qPrintable(names[items[0]])); - - for(int n = 0; n < items.count(); ++n) - { - names[items[n]] = makeUniqueName(items, names, list, n); - //printf(" %d: reassigning: [%s]\n", items[n], qPrintable(names[items[n]])); - } - } - - return names; + QStringList names; + + // give a base name to all certs first + foreach (const Certificate &cert, list) { + names += baseCertName(cert.subjectInfo()); + } + + // come up with a collision list + QList< QList > itemCollisions; + foreach (const QString &name, names) { + // anyone else using this name? + QList items = findSameName(name, names); + if (items.count() > 1) { + // don't save duplicate collisions + bool haveAlready = false; + foreach (const QList &other, itemCollisions) { + foreach (int n, items) { + if (other.contains(n)) { + haveAlready = true; + break; + } + } + + if (haveAlready) { + break; + } + } + + if (haveAlready) { + continue; + } + + itemCollisions += items; + } + } + + // resolve collisions by providing extra details + foreach (const QList &items, itemCollisions) { + //printf("%d items are using [%s]\n", items.count(), qPrintable(names[items[0]])); + + for (int n = 0; n < items.count(); ++n) { + names[items[n]] = makeUniqueName(items, names, list, n); + //printf(" %d: reassigning: [%s]\n", items[n], qPrintable(names[items[n]])); + } + } + + return names; } //---------------------------------------------------------------------------- // CertificateInfoType //---------------------------------------------------------------------------- class CertificateInfoType::Private : public QSharedData { public: - CertificateInfoType::Section section; - int known; - QString id; - - Private() : - section(CertificateInfoType::DN), - known(-1) - { - } + CertificateInfoType::Section section; + int known; + QString id; + + Private() : + section(CertificateInfoType::DN), + known(-1) + { + } }; CertificateInfoType::CertificateInfoType() -:d(new Private) + : d(new Private) { } CertificateInfoType::CertificateInfoType(CertificateInfoTypeKnown known) -:d(new Private) + : d(new Private) { - d->section = knownToSection(known); - d->known = known; - d->id = knownToId(known); // always valid + d->section = knownToSection(known); + d->known = known; + d->id = knownToId(known); // always valid } CertificateInfoType::CertificateInfoType(const QString &id, Section section) -:d(new Private) + : d(new Private) { - d->section = section; - d->known = idToKnown(id); // can be -1 for unknown - d->id = id; + d->section = section; + d->known = idToKnown(id); // can be -1 for unknown + d->id = id; } CertificateInfoType::CertificateInfoType(const CertificateInfoType &from) -:d(from.d) + : d(from.d) { } CertificateInfoType::~CertificateInfoType() { } -CertificateInfoType & CertificateInfoType::operator=(const CertificateInfoType &from) +CertificateInfoType &CertificateInfoType::operator=(const CertificateInfoType &from) { - d = from.d; - return *this; + d = from.d; + return *this; } CertificateInfoType::Section CertificateInfoType::section() const { - return d->section; + return d->section; } CertificateInfoTypeKnown CertificateInfoType::known() const { - return (CertificateInfoTypeKnown)d->known; + return (CertificateInfoTypeKnown)d->known; } QString CertificateInfoType::id() const { - return d->id; + return d->id; } bool CertificateInfoType::operator<(const CertificateInfoType &other) const { - // sort by knowns (in enum order), then by ids (in string order) - if(d->known != -1) - { - if(other.d->known == -1) - return true; - else if(d->known < other.d->known) - return true; - else - return false; - } - else - { - if(other.d->known != -1) - return false; - else if(d->id < other.d->id) - return true; - else - return false; - } + // sort by knowns (in enum order), then by ids (in string order) + if (d->known != -1) { + if (other.d->known == -1) { + return true; + } else if (d->known < other.d->known) { + return true; + } else { + return false; + } + } else { + if (other.d->known != -1) { + return false; + } else if (d->id < other.d->id) { + return true; + } else { + return false; + } + } } bool CertificateInfoType::operator==(const CertificateInfoType &other) const { - // are both known types? - if(d->known != -1 && other.d->known != -1) - { - // if so, compare the ints - if(d->known != other.d->known) - return false; - } - else - { - // otherwise, compare the string ids - if(d->id != other.d->id) - return false; - } + // are both known types? + if (d->known != -1 && other.d->known != -1) { + // if so, compare the ints + if (d->known != other.d->known) { + return false; + } + } else { + // otherwise, compare the string ids + if (d->id != other.d->id) { + return false; + } + } - if(d->section != other.d->section) - return false; + if (d->section != other.d->section) { + return false; + } - return true; + return true; } //---------------------------------------------------------------------------- // CertificateInfoPair //---------------------------------------------------------------------------- class CertificateInfoPair::Private : public QSharedData { public: - CertificateInfoType type; - QString value; + CertificateInfoType type; + QString value; }; CertificateInfoPair::CertificateInfoPair() -:d(new Private) + : d(new Private) { } CertificateInfoPair::CertificateInfoPair(const CertificateInfoType &type, const QString &value) -:d(new Private) + : d(new Private) { - d->type = type; - d->value = value; + d->type = type; + d->value = value; } CertificateInfoPair::CertificateInfoPair(const CertificateInfoPair &from) -:d(from.d) + : d(from.d) { } CertificateInfoPair::~CertificateInfoPair() { } -CertificateInfoPair & CertificateInfoPair::operator=(const CertificateInfoPair &from) +CertificateInfoPair &CertificateInfoPair::operator=(const CertificateInfoPair &from) { - d = from.d; - return *this; + d = from.d; + return *this; } CertificateInfoType CertificateInfoPair::type() const { - return d->type; + return d->type; } QString CertificateInfoPair::value() const { - return d->value; + return d->value; } bool CertificateInfoPair::operator==(const CertificateInfoPair &other) const { - if(d->type == other.d->type && d->value == other.d->value) - return true; - return false; + if (d->type == other.d->type && d->value == other.d->value) { + return true; + } + return false; } //---------------------------------------------------------------------------- // ConstraintType //---------------------------------------------------------------------------- class ConstraintType::Private : public QSharedData { public: - ConstraintType::Section section; - int known; - QString id; - - Private() : - section(ConstraintType::KeyUsage), - known(-1) - { - } + ConstraintType::Section section; + int known; + QString id; + + Private() : + section(ConstraintType::KeyUsage), + known(-1) + { + } }; ConstraintType::ConstraintType() -:d(new Private) + : d(new Private) { } ConstraintType::ConstraintType(ConstraintTypeKnown known) -:d(new Private) + : d(new Private) { - d->section = constraintKnownToSection(known); - d->known = known; - d->id = constraintKnownToId(known); // always valid + d->section = constraintKnownToSection(known); + d->known = known; + d->id = constraintKnownToId(known); // always valid } ConstraintType::ConstraintType(const QString &id, Section section) -:d(new Private) + : d(new Private) { - d->section = section; - d->known = constraintIdToKnown(id); // can be -1 for unknown - d->id = id; + d->section = section; + d->known = constraintIdToKnown(id); // can be -1 for unknown + d->id = id; } ConstraintType::ConstraintType(const ConstraintType &from) -:d(from.d) + : d(from.d) { } ConstraintType::~ConstraintType() { } -ConstraintType & ConstraintType::operator=(const ConstraintType &from) +ConstraintType &ConstraintType::operator=(const ConstraintType &from) { - d = from.d; - return *this; + d = from.d; + return *this; } ConstraintType::Section ConstraintType::section() const { - return d->section; + return d->section; } ConstraintTypeKnown ConstraintType::known() const { - return (ConstraintTypeKnown)d->known; + return (ConstraintTypeKnown)d->known; } QString ConstraintType::id() const { - return d->id; + return d->id; } bool ConstraintType::operator<(const ConstraintType &other) const { - // sort by knowns (in enum order), then by ids (in string order) - if(d->known != -1) - { - if(other.d->known == -1) - return true; - else if(d->known < other.d->known) - return true; - else - return false; - } - else - { - if(other.d->known != -1) - return false; - else if(d->id < other.d->id) - return true; - else - return false; - } + // sort by knowns (in enum order), then by ids (in string order) + if (d->known != -1) { + if (other.d->known == -1) { + return true; + } else if (d->known < other.d->known) { + return true; + } else { + return false; + } + } else { + if (other.d->known != -1) { + return false; + } else if (d->id < other.d->id) { + return true; + } else { + return false; + } + } } bool ConstraintType::operator==(const ConstraintType &other) const { - // are both known types? - if(d->known != -1 && other.d->known != -1) - { - // if so, compare the ints - if(d->known != other.d->known) - return false; - } - else - { - // otherwise, compare the string ids - if(d->id != other.d->id) - return false; - } + // are both known types? + if (d->known != -1 && other.d->known != -1) { + // if so, compare the ints + if (d->known != other.d->known) { + return false; + } + } else { + // otherwise, compare the string ids + if (d->id != other.d->id) { + return false; + } + } - if(d->section != other.d->section) - return false; + if (d->section != other.d->section) { + return false; + } - return true; + return true; } //---------------------------------------------------------------------------- // CertificateOptions //---------------------------------------------------------------------------- class CertificateOptions::Private { public: - CertificateRequestFormat format; - - QString challenge; - CertificateInfoOrdered info; - CertificateInfo infoMap; - Constraints constraints; - QStringList policies; - QStringList crlLocations, issuerLocations, ocspLocations; - bool isCA; - int pathLimit; - BigInteger serial; - QDateTime start, end; - - Private() : isCA(false), pathLimit(0) - { - } + CertificateRequestFormat format; + + QString challenge; + CertificateInfoOrdered info; + CertificateInfo infoMap; + Constraints constraints; + QStringList policies; + QStringList crlLocations, issuerLocations, ocspLocations; + bool isCA; + int pathLimit; + BigInteger serial; + QDateTime start, end; + + Private() : isCA(false), pathLimit(0) + { + } }; CertificateOptions::CertificateOptions(CertificateRequestFormat f) { - d = new Private; - d->format = f; + d = new Private; + d->format = f; } CertificateOptions::CertificateOptions(const CertificateOptions &from) { - d = new Private(*from.d); + d = new Private(*from.d); } CertificateOptions::~CertificateOptions() { - delete d; + delete d; } -CertificateOptions & CertificateOptions::operator=(const CertificateOptions &from) +CertificateOptions &CertificateOptions::operator=(const CertificateOptions &from) { - *d = *from.d; - return *this; + *d = *from.d; + return *this; } CertificateRequestFormat CertificateOptions::format() const { - return d->format; + return d->format; } void CertificateOptions::setFormat(CertificateRequestFormat f) { - d->format = f; + d->format = f; } bool CertificateOptions::isValid() const { - // logic from Botan - if(d->infoMap.value(CommonName).isEmpty() || d->infoMap.value(Country).isEmpty()) - return false; - if(d->infoMap.value(Country).length() != 2) - return false; - if(d->start >= d->end) - return false; - return true; + // logic from Botan + if (d->infoMap.value(CommonName).isEmpty() || d->infoMap.value(Country).isEmpty()) { + return false; + } + if (d->infoMap.value(Country).length() != 2) { + return false; + } + if (d->start >= d->end) { + return false; + } + return true; } QString CertificateOptions::challenge() const { - return d->challenge; + return d->challenge; } CertificateInfo CertificateOptions::info() const { - return d->infoMap; + return d->infoMap; } CertificateInfoOrdered CertificateOptions::infoOrdered() const { - return d->info; + return d->info; } Constraints CertificateOptions::constraints() const { - return d->constraints; + return d->constraints; } QStringList CertificateOptions::policies() const { - return d->policies; + return d->policies; } QStringList CertificateOptions::crlLocations() const { - return d->crlLocations; + return d->crlLocations; } QStringList CertificateOptions::issuerLocations() const { - return d->issuerLocations; + return d->issuerLocations; } QStringList CertificateOptions::ocspLocations() const { - return d->ocspLocations; + return d->ocspLocations; } bool CertificateOptions::isCA() const { - return d->isCA; + return d->isCA; } int CertificateOptions::pathLimit() const { - return d->pathLimit; + return d->pathLimit; } BigInteger CertificateOptions::serialNumber() const { - return d->serial; + return d->serial; } QDateTime CertificateOptions::notValidBefore() const { - return d->start; + return d->start; } QDateTime CertificateOptions::notValidAfter() const { - return d->end; + return d->end; } void CertificateOptions::setChallenge(const QString &s) { - d->challenge = s; + d->challenge = s; } void CertificateOptions::setInfo(const CertificateInfo &info) { - d->info = mapToOrdered(info); - d->infoMap = info; + d->info = mapToOrdered(info); + d->infoMap = info; } void CertificateOptions::setInfoOrdered(const CertificateInfoOrdered &info) { - d->info = info; - d->infoMap = orderedToMap(info); + d->info = info; + d->infoMap = orderedToMap(info); } void CertificateOptions::setConstraints(const Constraints &constraints) { - d->constraints = constraints; + d->constraints = constraints; } void CertificateOptions::setPolicies(const QStringList &policies) { - d->policies = policies; + d->policies = policies; } void CertificateOptions::setCRLLocations(const QStringList &locations) { - d->crlLocations = locations; + d->crlLocations = locations; } void CertificateOptions::setIssuerLocations(const QStringList &locations) { - d->issuerLocations = locations; + d->issuerLocations = locations; } void CertificateOptions::setOCSPLocations(const QStringList &locations) { - d->ocspLocations = locations; + d->ocspLocations = locations; } void CertificateOptions::setAsCA(int pathLimit) { - d->isCA = true; - d->pathLimit = pathLimit; + d->isCA = true; + d->pathLimit = pathLimit; } void CertificateOptions::setAsUser() { - d->isCA = false; - d->pathLimit = 0; + d->isCA = false; + d->pathLimit = 0; } void CertificateOptions::setSerialNumber(const BigInteger &i) { - d->serial = i; + d->serial = i; } void CertificateOptions::setValidityPeriod(const QDateTime &start, const QDateTime &end) { - d->start = start; - d->end = end; + d->start = start; + d->end = end; } //---------------------------------------------------------------------------- @@ -1199,1074 +1185,1093 @@ // return: size 4 = ipv4, size 16 = ipv6, size 0 = error static QByteArray ipaddr_str2bin(const QString &str) { - // ipv6 - if(str.contains(':')) - { - QStringList parts = str.split(':', QString::KeepEmptyParts); - if(parts.count() < 3 || parts.count() > 8) - return QByteArray(); - - QByteArray ipv6(16, 0); - int at = 16; - int fill = 9 - parts.count(); - for(int n = parts.count() - 1; n >= 0; --n) - { - if(at <= 0) - return QByteArray(); - - if(parts[n].isEmpty()) - { - if(n == parts.count() - 1) - { - if(!parts[n - 1].isEmpty()) - return QByteArray(); - ipv6[--at] = 0; - ipv6[--at] = 0; - } - else if(n == 0) - { - if(!parts[n + 1].isEmpty()) - return QByteArray(); - ipv6[--at] = 0; - ipv6[--at] = 0; - } - else - { - for(int i = 0; i < fill; ++i) - { - if(at <= 0) - return QByteArray(); - ipv6[--at] = 0; - ipv6[--at] = 0; - } - } - } - else - { - if(parts[n].indexOf('.') == -1) - { - bool ok; - int x = parts[n].toInt(&ok, 16); - if(!ok || x < 0 || x > 0xffff) - return QByteArray(); - ipv6[--at] = x & 0xff; - ipv6[--at] = (x >> 8) & 0xff; - } - else - { - if(n != parts.count() - 1) - return QByteArray(); - - QByteArray buf = ipaddr_str2bin(parts[n]); - if(buf.isEmpty()) - return QByteArray(); - - ipv6[--at] = buf[3]; - ipv6[--at] = buf[2]; - ipv6[--at] = buf[1]; - ipv6[--at] = buf[0]; - --fill; - } - } - } - - return ipv6; - } - else if(str.contains('.')) - { - QStringList parts = str.split('.', QString::KeepEmptyParts); - if(parts.count() != 4) - return QByteArray(); - - QByteArray out(4, 0); - for(int n = 0; n < 4; ++n) - { - bool ok; - int x = parts[n].toInt(&ok); - if(!ok || x < 0 || x > 0xff) - return QByteArray(); - out[n] = (unsigned char)x; - } - return out; - } - else - return QByteArray(); + // ipv6 + if (str.contains(':')) { + QStringList parts = str.split(':', QString::KeepEmptyParts); + if (parts.count() < 3 || parts.count() > 8) { + return QByteArray(); + } + + QByteArray ipv6(16, 0); + int at = 16; + int fill = 9 - parts.count(); + for (int n = parts.count() - 1; n >= 0; --n) { + if (at <= 0) { + return QByteArray(); + } + + if (parts[n].isEmpty()) { + if (n == parts.count() - 1) { + if (!parts[n - 1].isEmpty()) { + return QByteArray(); + } + ipv6[--at] = 0; + ipv6[--at] = 0; + } else if (n == 0) { + if (!parts[n + 1].isEmpty()) { + return QByteArray(); + } + ipv6[--at] = 0; + ipv6[--at] = 0; + } else { + for (int i = 0; i < fill; ++i) { + if (at <= 0) { + return QByteArray(); + } + ipv6[--at] = 0; + ipv6[--at] = 0; + } + } + } else { + if (parts[n].indexOf('.') == -1) { + bool ok; + int x = parts[n].toInt(&ok, 16); + if (!ok || x < 0 || x > 0xffff) { + return QByteArray(); + } + ipv6[--at] = x & 0xff; + ipv6[--at] = (x >> 8) & 0xff; + } else { + if (n != parts.count() - 1) { + return QByteArray(); + } + + QByteArray buf = ipaddr_str2bin(parts[n]); + if (buf.isEmpty()) { + return QByteArray(); + } + + ipv6[--at] = buf[3]; + ipv6[--at] = buf[2]; + ipv6[--at] = buf[1]; + ipv6[--at] = buf[0]; + --fill; + } + } + } + + return ipv6; + } else if (str.contains('.')) { + QStringList parts = str.split('.', QString::KeepEmptyParts); + if (parts.count() != 4) { + return QByteArray(); + } + + QByteArray out(4, 0); + for (int n = 0; n < 4; ++n) { + bool ok; + int x = parts[n].toInt(&ok); + if (!ok || x < 0 || x > 0xff) { + return QByteArray(); + } + out[n] = (unsigned char)x; + } + return out; + } else { + return QByteArray(); + } } // acedomain must be all lowercase, with no trailing dot or wildcards static bool cert_match_domain(const QString &certname, const QString &acedomain) { - // KSSL strips start/end whitespace, even though such whitespace is - // probably not legal anyway. (compat) - QString name = certname.trimmed(); - - // KSSL strips trailing dot, even though the dot is probably not - // legal anyway. (compat) - if(name.length() > 0 && name[name.length()-1] == '.') - name.truncate(name.length()-1); - - // after our compatibility modifications, make sure the name isn't - // empty. - if(name.isEmpty()) - return false; - - // lowercase, for later performing case insensitive matching - name = name.toLower(); - - // ensure the cert field contains valid characters only - if(QRegExp("[^a-z0-9\\.\\*\\-]").indexIn(name) >= 0) - return false; - - // hack into parts, and require at least 1 part - QStringList parts_name = name.split('.', QString::KeepEmptyParts); - if(parts_name.isEmpty()) - return false; - - // KSSL checks to make sure the last two parts don't contain - // wildcards. I don't know where it is written that this - // should be done, but for compat sake we'll do it. - if(parts_name[parts_name.count()-1].contains('*')) - return false; - if(parts_name.count() >= 2 && parts_name[parts_name.count()-2].contains('*')) - return false; - - QStringList parts_compare = acedomain.split('.', QString::KeepEmptyParts); - if(parts_compare.isEmpty()) - return false; - - // don't allow empty parts - foreach(const QString &s, parts_name) - { - if(s.isEmpty()) - return false; - } - foreach(const QString &s, parts_compare) - { - if(s.isEmpty()) - return false; - } - - // RFC2818: "Names may contain the wildcard character * which is - // considered to match any single domain name component or - // component fragment. E.g., *.a.com matches foo.a.com but not - // bar.foo.a.com. f*.com matches foo.com but not bar.com." - // - // This means that for the domain to match it must have the - // same number of components, wildcards or not. If there are - // wildcards, their scope must only be within the component - // they reside in. - // - // First, make sure the number of parts is equal. - if(parts_name.count() != parts_compare.count()) - return false; - - // Now compare each part - for(int n = 0; n < parts_name.count(); ++n) - { - const QString &p1 = parts_name[n]; - const QString &p2 = parts_compare[n]; - - if(!QRegExp(p1, Qt::CaseSensitive, QRegExp::Wildcard).exactMatch(p2)) - return false; - } - - return true; + // KSSL strips start/end whitespace, even though such whitespace is + // probably not legal anyway. (compat) + QString name = certname.trimmed(); + + // KSSL strips trailing dot, even though the dot is probably not + // legal anyway. (compat) + if (name.length() > 0 && name[name.length() - 1] == '.') { + name.truncate(name.length() - 1); + } + + // after our compatibility modifications, make sure the name isn't + // empty. + if (name.isEmpty()) { + return false; + } + + // lowercase, for later performing case insensitive matching + name = name.toLower(); + + // ensure the cert field contains valid characters only + if (QRegExp("[^a-z0-9\\.\\*\\-]").indexIn(name) >= 0) { + return false; + } + + // hack into parts, and require at least 1 part + QStringList parts_name = name.split('.', QString::KeepEmptyParts); + if (parts_name.isEmpty()) { + return false; + } + + // KSSL checks to make sure the last two parts don't contain + // wildcards. I don't know where it is written that this + // should be done, but for compat sake we'll do it. + if (parts_name[parts_name.count() - 1].contains('*')) { + return false; + } + if (parts_name.count() >= 2 && parts_name[parts_name.count() - 2].contains('*')) { + return false; + } + + QStringList parts_compare = acedomain.split('.', QString::KeepEmptyParts); + if (parts_compare.isEmpty()) { + return false; + } + + // don't allow empty parts + foreach (const QString &s, parts_name) { + if (s.isEmpty()) { + return false; + } + } + foreach (const QString &s, parts_compare) { + if (s.isEmpty()) { + return false; + } + } + + // RFC2818: "Names may contain the wildcard character * which is + // considered to match any single domain name component or + // component fragment. E.g., *.a.com matches foo.a.com but not + // bar.foo.a.com. f*.com matches foo.com but not bar.com." + // + // This means that for the domain to match it must have the + // same number of components, wildcards or not. If there are + // wildcards, their scope must only be within the component + // they reside in. + // + // First, make sure the number of parts is equal. + if (parts_name.count() != parts_compare.count()) { + return false; + } + + // Now compare each part + for (int n = 0; n < parts_name.count(); ++n) { + const QString &p1 = parts_name[n]; + const QString &p2 = parts_compare[n]; + + if (!QRegExp(p1, Qt::CaseSensitive, QRegExp::Wildcard).exactMatch(p2)) { + return false; + } + } + + return true; } // ipaddress must be an ipv4 or ipv6 address in binary format static bool cert_match_ipaddress(const QString &certname, const QByteArray &ipaddress) { - // KSSL strips start/end whitespace, even though such whitespace is - // probably not legal anyway. (compat) - QString name = certname.trimmed(); + // KSSL strips start/end whitespace, even though such whitespace is + // probably not legal anyway. (compat) + QString name = certname.trimmed(); - // KSSL accepts IPv6 in brackets, which is usually done for URIs, but - // IMO sounds very strange for a certificate. We'll follow this - // behavior anyway. (compat) - if(name.length() >= 2 && name[0] == '[' && name[name.length()-1] == ']') - name = name.mid(1, name.length() - 2); // chop off brackets + // KSSL accepts IPv6 in brackets, which is usually done for URIs, but + // IMO sounds very strange for a certificate. We'll follow this + // behavior anyway. (compat) + if (name.length() >= 2 && name[0] == '[' && name[name.length() - 1] == ']') { + name = name.mid(1, name.length() - 2); // chop off brackets + } - // after our compatibility modifications, make sure the name isn't - // empty. - if(name.isEmpty()) - return false; + // after our compatibility modifications, make sure the name isn't + // empty. + if (name.isEmpty()) { + return false; + } - // convert to binary form - QByteArray addr = ipaddr_str2bin(name); - if(addr.isEmpty()) - return false; + // convert to binary form + QByteArray addr = ipaddr_str2bin(name); + if (addr.isEmpty()) { + return false; + } - // not the same? - if(addr != ipaddress) - return false; + // not the same? + if (addr != ipaddress) { + return false; + } - return true; + return true; } class Certificate::Private : public QSharedData { public: - CertificateInfo subjectInfoMap, issuerInfoMap; - - void update(CertContext *c) - { - if(c) - { - subjectInfoMap = orderedToMap(c->props()->subject); - issuerInfoMap = orderedToMap(c->props()->issuer); - } - else - { - subjectInfoMap = CertificateInfo(); - issuerInfoMap = CertificateInfo(); - } - } + CertificateInfo subjectInfoMap, issuerInfoMap; + + void update(CertContext *c) + { + if (c) { + subjectInfoMap = orderedToMap(c->props()->subject); + issuerInfoMap = orderedToMap(c->props()->issuer); + } else { + subjectInfoMap = CertificateInfo(); + issuerInfoMap = CertificateInfo(); + } + } }; Certificate::Certificate() -:d(new Private) + : d(new Private) { } Certificate::Certificate(const QString &fileName) -:d(new Private) + : d(new Private) { - *this = fromPEMFile(fileName, 0, QString()); + *this = fromPEMFile(fileName, 0, QString()); } Certificate::Certificate(const CertificateOptions &opts, const PrivateKey &key, const QString &provider) -:d(new Private) + : d(new Private) { - CertContext *c = static_cast(getContext("cert", provider)); - if(c->createSelfSigned(opts, *(static_cast(key.context())))) - change(c); - else - delete c; + CertContext *c = static_cast(getContext("cert", provider)); + if (c->createSelfSigned(opts, *(static_cast(key.context())))) { + change(c); + } else { + delete c; + } } Certificate::Certificate(const Certificate &from) -:Algorithm(from), d(from.d) + : Algorithm(from), d(from.d) { } Certificate::~Certificate() { } -Certificate & Certificate::operator=(const Certificate &from) +Certificate &Certificate::operator=(const Certificate &from) { - Algorithm::operator=(from); - d = from.d; - return *this; + Algorithm::operator=(from); + d = from.d; + return *this; } bool Certificate::isNull() const { - return (!context() ? true : false); + return (!context() ? true : false); } QDateTime Certificate::notValidBefore() const { - return static_cast(context())->props()->start; + return static_cast(context())->props()->start; } QDateTime Certificate::notValidAfter() const { - return static_cast(context())->props()->end; + return static_cast(context())->props()->end; } CertificateInfo Certificate::subjectInfo() const { - return d->subjectInfoMap; + return d->subjectInfoMap; } CertificateInfoOrdered Certificate::subjectInfoOrdered() const { - return static_cast(context())->props()->subject; + return static_cast(context())->props()->subject; } CertificateInfo Certificate::issuerInfo() const { - return d->issuerInfoMap; + return d->issuerInfoMap; } CertificateInfoOrdered Certificate::issuerInfoOrdered() const { - return static_cast(context())->props()->issuer; + return static_cast(context())->props()->issuer; } Constraints Certificate::constraints() const { - return static_cast(context())->props()->constraints; + return static_cast(context())->props()->constraints; } QStringList Certificate::policies() const { - return static_cast(context())->props()->policies; + return static_cast(context())->props()->policies; } QStringList Certificate::crlLocations() const { - return static_cast(context())->props()->crlLocations; + return static_cast(context())->props()->crlLocations; } QStringList Certificate::issuerLocations() const { - return static_cast(context())->props()->issuerLocations; + return static_cast(context())->props()->issuerLocations; } QStringList Certificate::ocspLocations() const { - return static_cast(context())->props()->ocspLocations; + return static_cast(context())->props()->ocspLocations; } QString Certificate::commonName() const { - return d->subjectInfoMap.value(CommonName); + return d->subjectInfoMap.value(CommonName); } BigInteger Certificate::serialNumber() const { - return static_cast(context())->props()->serial; + return static_cast(context())->props()->serial; } PublicKey Certificate::subjectPublicKey() const { - PKeyContext *c = static_cast(context())->subjectPublicKey(); - PublicKey key; - key.change(c); - return key; + PKeyContext *c = static_cast(context())->subjectPublicKey(); + PublicKey key; + key.change(c); + return key; } bool Certificate::isCA() const { - return static_cast(context())->props()->isCA; + return static_cast(context())->props()->isCA; } bool Certificate::isSelfSigned() const { - return static_cast(context())->props()->isSelfSigned; + return static_cast(context())->props()->isSelfSigned; } bool Certificate::isIssuerOf(const Certificate &other) const { - const CertContext *cc = static_cast(other.context()); - return static_cast(context())->isIssuerOf(cc); + const CertContext *cc = static_cast(other.context()); + return static_cast(context())->isIssuerOf(cc); } int Certificate::pathLimit() const { - return static_cast(context())->props()->pathLimit; + return static_cast(context())->props()->pathLimit; } SignatureAlgorithm Certificate::signatureAlgorithm() const { - return static_cast(context())->props()->sigalgo; + return static_cast(context())->props()->sigalgo; } QByteArray Certificate::subjectKeyId() const { - return static_cast(context())->props()->subjectId; + return static_cast(context())->props()->subjectId; } QByteArray Certificate::issuerKeyId() const { - return static_cast(context())->props()->issuerId; + return static_cast(context())->props()->issuerId; } Validity Certificate::validate(const CertificateCollection &trusted, const CertificateCollection &untrusted, UsageMode u, ValidateFlags vf) const { - QList issuers = trusted.certificates() + untrusted.certificates(); - CertificateChain chain; - chain += *this; - Validity result; - chain = chain.complete(issuers, &result); - if(result != ValidityGood) - return result; - return chain.validate(trusted, untrusted.crls(), u, vf); + QList issuers = trusted.certificates() + untrusted.certificates(); + CertificateChain chain; + chain += *this; + Validity result; + chain = chain.complete(issuers, &result); + if (result != ValidityGood) { + return result; + } + return chain.validate(trusted, untrusted.crls(), u, vf); } QByteArray Certificate::toDER() const { - return static_cast(context())->toDER(); + return static_cast(context())->toDER(); } QString Certificate::toPEM() const { - return static_cast(context())->toPEM(); + return static_cast(context())->toPEM(); } bool Certificate::toPEMFile(const QString &fileName) const { - return stringToFile(fileName, toPEM()); + return stringToFile(fileName, toPEM()); } Certificate Certificate::fromDER(const QByteArray &a, ConvertResult *result, const QString &provider) { - Certificate c; - CertContext *cc = static_cast(getContext("cert", provider)); - ConvertResult r = cc->fromDER(a); - if(result) - *result = r; - if(r == ConvertGood) - c.change(cc); - else - delete cc; - return c; + Certificate c; + CertContext *cc = static_cast(getContext("cert", provider)); + ConvertResult r = cc->fromDER(a); + if (result) { + *result = r; + } + if (r == ConvertGood) { + c.change(cc); + } else { + delete cc; + } + return c; } Certificate Certificate::fromPEM(const QString &s, ConvertResult *result, const QString &provider) { - Certificate c; - CertContext *cc = static_cast(getContext("cert", provider)); - ConvertResult r = cc->fromPEM(s); - if(result) - *result = r; - if(r == ConvertGood) - c.change(cc); - else - delete cc; - return c; + Certificate c; + CertContext *cc = static_cast(getContext("cert", provider)); + ConvertResult r = cc->fromPEM(s); + if (result) { + *result = r; + } + if (r == ConvertGood) { + c.change(cc); + } else { + delete cc; + } + return c; } Certificate Certificate::fromPEMFile(const QString &fileName, ConvertResult *result, const QString &provider) { - QString pem; - if(!stringFromFile(fileName, &pem)) - { - if(result) - *result = ErrorFile; - return Certificate(); - } - return fromPEM(pem, result, provider); + QString pem; + if (!stringFromFile(fileName, &pem)) { + if (result) { + *result = ErrorFile; + } + return Certificate(); + } + return fromPEM(pem, result, provider); } // check for ip addresses in iPAddress, dNSName, then commonName // for all else, check in dNSName, then commonName bool Certificate::matchesHostName(const QString &host) const { - QByteArray ipaddr = ipaddr_str2bin(host); - if(!ipaddr.isEmpty()) // ip address - { - // check iPAddress - foreach(const QString &s, subjectInfo().values(IPAddress)) - { - if(cert_match_ipaddress(s, ipaddr)) - return true; - } - - // check dNSName - foreach(const QString &s, subjectInfo().values(DNS)) - { - if(cert_match_ipaddress(s, ipaddr)) - return true; - } - - // check commonName - foreach(const QString &s, subjectInfo().values(CommonName)) - { - if(cert_match_ipaddress(s, ipaddr)) - return true; - } - } - else // domain - { - // lowercase - QString name = host.toLower(); - - // ACE - name = QString::fromLatin1(QUrl::toAce(name)); - - // don't allow wildcards in the comparison host - if(name.contains('*')) - return false; - - // strip out trailing dot - if(name.length() > 0 && name[name.length()-1] == '.') - name.truncate(name.length()-1); - - // make sure the name is not empty after our modifications - if(name.isEmpty()) - return false; - - // check dNSName - foreach(const QString &s, subjectInfo().values(DNS)) - { - if(cert_match_domain(s, name)) - return true; - } - - // check commonName - foreach(const QString &s, subjectInfo().values(CommonName)) - { - if(cert_match_domain(s, name)) - return true; - } - } - - return false; + QByteArray ipaddr = ipaddr_str2bin(host); + if (!ipaddr.isEmpty()) { // ip address + // check iPAddress + foreach (const QString &s, subjectInfo().values(IPAddress)) { + if (cert_match_ipaddress(s, ipaddr)) { + return true; + } + } + + // check dNSName + foreach (const QString &s, subjectInfo().values(DNS)) { + if (cert_match_ipaddress(s, ipaddr)) { + return true; + } + } + + // check commonName + foreach (const QString &s, subjectInfo().values(CommonName)) { + if (cert_match_ipaddress(s, ipaddr)) { + return true; + } + } + } else { // domain + // lowercase + QString name = host.toLower(); + + // ACE + name = QString::fromLatin1(QUrl::toAce(name)); + + // don't allow wildcards in the comparison host + if (name.contains('*')) { + return false; + } + + // strip out trailing dot + if (name.length() > 0 && name[name.length() - 1] == '.') { + name.truncate(name.length() - 1); + } + + // make sure the name is not empty after our modifications + if (name.isEmpty()) { + return false; + } + + // check dNSName + foreach (const QString &s, subjectInfo().values(DNS)) { + if (cert_match_domain(s, name)) { + return true; + } + } + + // check commonName + foreach (const QString &s, subjectInfo().values(CommonName)) { + if (cert_match_domain(s, name)) { + return true; + } + } + } + + return false; } bool Certificate::operator==(const Certificate &otherCert) const { - if(isNull()) - { - if(otherCert.isNull()) - return true; - else - return false; - } - else if(otherCert.isNull()) - return false; + if (isNull()) { + if (otherCert.isNull()) { + return true; + } else { + return false; + } + } else if (otherCert.isNull()) { + return false; + } - const CertContext *other = static_cast(otherCert.context()); - return static_cast(context())->compare(other); + const CertContext *other = static_cast(otherCert.context()); + return static_cast(context())->compare(other); } void Certificate::change(CertContext *c) { - Algorithm::change(c); - d->update(static_cast(context())); + Algorithm::change(c); + d->update(static_cast(context())); } Validity Certificate::chain_validate(const CertificateChain &chain, const CertificateCollection &trusted, const QList &untrusted_crls, UsageMode u, ValidateFlags vf) const { - QList chain_list; - QList trusted_list; - QList crl_list; - - QList chain_certs = chain; - QList trusted_certs = trusted.certificates(); - QList crls = trusted.crls() + untrusted_crls; - - for(int n = 0; n < chain_certs.count(); ++n) - { - CertContext *c = static_cast(chain_certs[n].context()); - chain_list += c; - } - for(int n = 0; n < trusted_certs.count(); ++n) - { - CertContext *c = static_cast(trusted_certs[n].context()); - trusted_list += c; - } - for(int n = 0; n < crls.count(); ++n) - { - CRLContext *c = static_cast(crls[n].context()); - crl_list += c; - } - - return static_cast(context())->validate_chain(chain_list, trusted_list, crl_list, u, vf); + QList chain_list; + QList trusted_list; + QList crl_list; + + QList chain_certs = chain; + QList trusted_certs = trusted.certificates(); + QList crls = trusted.crls() + untrusted_crls; + + for (int n = 0; n < chain_certs.count(); ++n) { + CertContext *c = static_cast(chain_certs[n].context()); + chain_list += c; + } + for (int n = 0; n < trusted_certs.count(); ++n) { + CertContext *c = static_cast(trusted_certs[n].context()); + trusted_list += c; + } + for (int n = 0; n < crls.count(); ++n) { + CRLContext *c = static_cast(crls[n].context()); + crl_list += c; + } + + return static_cast(context())->validate_chain(chain_list, trusted_list, crl_list, u, vf); } CertificateChain Certificate::chain_complete(const CertificateChain &chain, const QList &issuers, Validity *result) const { - CertificateChain out; - QList pool = issuers + chain.mid(1); - out += chain.first(); - if(result) - *result = ValidityGood; - while(!out.last().isSelfSigned()) - { - // try to get next in chain - int at = -1; - for(int n = 0; n < pool.count(); ++n) - { - //QString str = QString("[%1] issued by [%2] ? ").arg(out.last().commonName()).arg(pool[n].commonName()); - if(pool[n].isIssuerOf(out.last())) - { - //printf("%s yes\n", qPrintable(str)); - at = n; - break; - } - //printf("%s no\n", qPrintable(str)); - } - if(at == -1) - { - if(result) - *result = ErrorInvalidCA; - break; - } - - // take it out of the pool - Certificate next = pool.takeAt(at); - - // make sure it isn't in the chain already (avoid loops) - if(out.contains(next)) - break; - - // append to the chain - out += next; - } - return out; + CertificateChain out; + QList pool = issuers + chain.mid(1); + out += chain.first(); + if (result) { + *result = ValidityGood; + } + while (!out.last().isSelfSigned()) { + // try to get next in chain + int at = -1; + for (int n = 0; n < pool.count(); ++n) { + //QString str = QString("[%1] issued by [%2] ? ").arg(out.last().commonName()).arg(pool[n].commonName()); + if (pool[n].isIssuerOf(out.last())) { + //printf("%s yes\n", qPrintable(str)); + at = n; + break; + } + //printf("%s no\n", qPrintable(str)); + } + if (at == -1) { + if (result) { + *result = ErrorInvalidCA; + } + break; + } + + // take it out of the pool + Certificate next = pool.takeAt(at); + + // make sure it isn't in the chain already (avoid loops) + if (out.contains(next)) { + break; + } + + // append to the chain + out += next; + } + return out; } //---------------------------------------------------------------------------- // CertificateRequest //---------------------------------------------------------------------------- class CertificateRequest::Private : public QSharedData { public: - CertificateInfo subjectInfoMap; - - void update(CSRContext *c) - { - if(c) - subjectInfoMap = orderedToMap(c->props()->subject); - else - subjectInfoMap = CertificateInfo(); - } + CertificateInfo subjectInfoMap; + + void update(CSRContext *c) + { + if (c) { + subjectInfoMap = orderedToMap(c->props()->subject); + } else { + subjectInfoMap = CertificateInfo(); + } + } }; CertificateRequest::CertificateRequest() -:d(new Private) + : d(new Private) { } CertificateRequest::CertificateRequest(const QString &fileName) -:d(new Private) + : d(new Private) { - *this = fromPEMFile(fileName, 0, QString()); + *this = fromPEMFile(fileName, 0, QString()); } CertificateRequest::CertificateRequest(const CertificateOptions &opts, const PrivateKey &key, const QString &provider) -:d(new Private) + : d(new Private) { - CSRContext *c = static_cast(getContext("csr", provider)); - if(c->createRequest(opts, *(static_cast(key.context())))) - change(c); - else - delete c; + CSRContext *c = static_cast(getContext("csr", provider)); + if (c->createRequest(opts, *(static_cast(key.context())))) { + change(c); + } else { + delete c; + } } CertificateRequest::CertificateRequest(const CertificateRequest &from) -:Algorithm(from), d(from.d) + : Algorithm(from), d(from.d) { } CertificateRequest::~CertificateRequest() { } -CertificateRequest & CertificateRequest::operator=(const CertificateRequest &from) +CertificateRequest &CertificateRequest::operator=(const CertificateRequest &from) { - Algorithm::operator=(from); - d = from.d; - return *this; + Algorithm::operator=(from); + d = from.d; + return *this; } bool CertificateRequest::isNull() const { - return (!context() ? true : false); + return (!context() ? true : false); } bool CertificateRequest::canUseFormat(CertificateRequestFormat f, const QString &provider) { - CSRContext *c = static_cast(getContext("csr", provider)); - bool ok = c->canUseFormat(f); - delete c; - return ok; + CSRContext *c = static_cast(getContext("csr", provider)); + bool ok = c->canUseFormat(f); + delete c; + return ok; } CertificateRequestFormat CertificateRequest::format() const { - if(isNull()) - return PKCS10; // some default so we don't explode - return static_cast(context())->props()->format; + if (isNull()) { + return PKCS10; // some default so we don't explode + } + return static_cast(context())->props()->format; } CertificateInfo CertificateRequest::subjectInfo() const { - return d->subjectInfoMap; + return d->subjectInfoMap; } CertificateInfoOrdered CertificateRequest::subjectInfoOrdered() const { - return static_cast(context())->props()->subject; + return static_cast(context())->props()->subject; } Constraints CertificateRequest::constraints() const { - return static_cast(context())->props()->constraints; + return static_cast(context())->props()->constraints; } QStringList CertificateRequest::policies() const { - return static_cast(context())->props()->policies; + return static_cast(context())->props()->policies; } PublicKey CertificateRequest::subjectPublicKey() const { - PKeyContext *c = static_cast(context())->subjectPublicKey(); - PublicKey key; - key.change(c); - return key; + PKeyContext *c = static_cast(context())->subjectPublicKey(); + PublicKey key; + key.change(c); + return key; } bool CertificateRequest::isCA() const { - return static_cast(context())->props()->isCA; + return static_cast(context())->props()->isCA; } int CertificateRequest::pathLimit() const { - return static_cast(context())->props()->pathLimit; + return static_cast(context())->props()->pathLimit; } QString CertificateRequest::challenge() const { - return static_cast(context())->props()->challenge; + return static_cast(context())->props()->challenge; } SignatureAlgorithm CertificateRequest::signatureAlgorithm() const { - return static_cast(context())->props()->sigalgo; + return static_cast(context())->props()->sigalgo; } bool CertificateRequest::operator==(const CertificateRequest &otherCsr) const { - if(isNull()) - { - if(otherCsr.isNull()) - return true; - else - return false; - } - else if(otherCsr.isNull()) - return false; + if (isNull()) { + if (otherCsr.isNull()) { + return true; + } else { + return false; + } + } else if (otherCsr.isNull()) { + return false; + } - const CSRContext *other = static_cast(otherCsr.context()); - return static_cast(context())->compare(other); + const CSRContext *other = static_cast(otherCsr.context()); + return static_cast(context())->compare(other); } QByteArray CertificateRequest::toDER() const { - return static_cast(context())->toDER(); + return static_cast(context())->toDER(); } QString CertificateRequest::toPEM() const { - return static_cast(context())->toPEM(); + return static_cast(context())->toPEM(); } bool CertificateRequest::toPEMFile(const QString &fileName) const { - return stringToFile(fileName, toPEM()); + return stringToFile(fileName, toPEM()); } CertificateRequest CertificateRequest::fromDER(const QByteArray &a, ConvertResult *result, const QString &provider) { - CertificateRequest c; - CSRContext *csr = static_cast(getContext("csr", provider)); - ConvertResult r = csr->fromDER(a); - if(result) - *result = r; - if(r == ConvertGood) - c.change(csr); - else - delete csr; - return c; + CertificateRequest c; + CSRContext *csr = static_cast(getContext("csr", provider)); + ConvertResult r = csr->fromDER(a); + if (result) { + *result = r; + } + if (r == ConvertGood) { + c.change(csr); + } else { + delete csr; + } + return c; } CertificateRequest CertificateRequest::fromPEM(const QString &s, ConvertResult *result, const QString &provider) { - CertificateRequest c; - CSRContext *csr = static_cast(getContext("csr", provider)); - ConvertResult r = csr->fromPEM(s); - if(result) - *result = r; - if(r == ConvertGood) - c.change(csr); - else - delete csr; - return c; + CertificateRequest c; + CSRContext *csr = static_cast(getContext("csr", provider)); + ConvertResult r = csr->fromPEM(s); + if (result) { + *result = r; + } + if (r == ConvertGood) { + c.change(csr); + } else { + delete csr; + } + return c; } CertificateRequest CertificateRequest::fromPEMFile(const QString &fileName, ConvertResult *result, const QString &provider) { - QString pem; - if(!stringFromFile(fileName, &pem)) - { - if(result) - *result = ErrorFile; - return CertificateRequest(); - } - return fromPEM(pem, result, provider); + QString pem; + if (!stringFromFile(fileName, &pem)) { + if (result) { + *result = ErrorFile; + } + return CertificateRequest(); + } + return fromPEM(pem, result, provider); } QString CertificateRequest::toString() const { - return static_cast(context())->toSPKAC(); + return static_cast(context())->toSPKAC(); } CertificateRequest CertificateRequest::fromString(const QString &s, ConvertResult *result, const QString &provider) { - CertificateRequest c; - CSRContext *csr = static_cast(getContext("csr", provider)); - ConvertResult r = csr->fromSPKAC(s); - if(result) - *result = r; - if(r == ConvertGood) - c.change(csr); - else - delete csr; - return c; + CertificateRequest c; + CSRContext *csr = static_cast(getContext("csr", provider)); + ConvertResult r = csr->fromSPKAC(s); + if (result) { + *result = r; + } + if (r == ConvertGood) { + c.change(csr); + } else { + delete csr; + } + return c; } void CertificateRequest::change(CSRContext *c) { - Algorithm::change(c); - d->update(static_cast(context())); + Algorithm::change(c); + d->update(static_cast(context())); } //---------------------------------------------------------------------------- // CRLEntry //---------------------------------------------------------------------------- CRLEntry::CRLEntry() { - _reason = Unspecified; + _reason = Unspecified; } CRLEntry::CRLEntry(const Certificate &c, Reason r) { - _serial = c.serialNumber(); - _time = QDateTime::currentDateTime(); - _reason = r; + _serial = c.serialNumber(); + _time = QDateTime::currentDateTime(); + _reason = r; } CRLEntry::CRLEntry(const BigInteger serial, const QDateTime &time, Reason r) { - _serial = serial; - _time = time; - _reason = r; + _serial = serial; + _time = time; + _reason = r; } CRLEntry::CRLEntry(const CRLEntry &from) -:_serial(from._serial), _time(from._time), _reason(from._reason) + : _serial(from._serial), _time(from._time), _reason(from._reason) { } CRLEntry::~CRLEntry() { } -CRLEntry & CRLEntry::operator=(const CRLEntry &from) +CRLEntry &CRLEntry::operator=(const CRLEntry &from) { - _serial = from._serial; - _time = from._time; - _reason = from._reason; - return *this; + _serial = from._serial; + _time = from._time; + _reason = from._reason; + return *this; } bool CRLEntry::isNull() const { - return (_time.isNull()); + return (_time.isNull()); } BigInteger CRLEntry::serialNumber() const { - return _serial; + return _serial; } QDateTime CRLEntry::time() const { - return _time; + return _time; } CRLEntry::Reason CRLEntry::reason() const { - return _reason; + return _reason; } bool CRLEntry::operator==(const CRLEntry &otherEntry) const { - if(isNull()) - { - if(otherEntry.isNull()) - return true; - else - return false; - } - else if(otherEntry.isNull()) - return false; - - if((_serial != otherEntry._serial) || - (_time != otherEntry._time) || - (_reason != otherEntry._reason)) - { - return false; - } - return true; + if (isNull()) { + if (otherEntry.isNull()) { + return true; + } else { + return false; + } + } else if (otherEntry.isNull()) { + return false; + } + + if ((_serial != otherEntry._serial) || + (_time != otherEntry._time) || + (_reason != otherEntry._reason)) { + return false; + } + return true; } bool CRLEntry::operator<(const CRLEntry &otherEntry) const { - if(isNull() || otherEntry.isNull()) - return false; + if (isNull() || otherEntry.isNull()) { + return false; + } - if(_serial < otherEntry._serial) - return true; + if (_serial < otherEntry._serial) { + return true; + } - return false; + return false; } //---------------------------------------------------------------------------- // CRL //---------------------------------------------------------------------------- class CRL::Private : public QSharedData { public: - CertificateInfo issuerInfoMap; - - void update(CRLContext *c) - { - if(c) - issuerInfoMap = orderedToMap(c->props()->issuer); - else - issuerInfoMap = CertificateInfo(); - } + CertificateInfo issuerInfoMap; + + void update(CRLContext *c) + { + if (c) { + issuerInfoMap = orderedToMap(c->props()->issuer); + } else { + issuerInfoMap = CertificateInfo(); + } + } }; CRL::CRL() -:d(new Private) + : d(new Private) { } CRL::CRL(const CRL &from) -:Algorithm(from), d(from.d) + : Algorithm(from), d(from.d) { } CRL::~CRL() { } -CRL & CRL::operator=(const CRL &from) +CRL &CRL::operator=(const CRL &from) { - Algorithm::operator=(from); - d = from.d; - return *this; + Algorithm::operator=(from); + d = from.d; + return *this; } bool CRL::isNull() const { - return (!context() ? true : false); + return (!context() ? true : false); } CertificateInfo CRL::issuerInfo() const { - return d->issuerInfoMap; + return d->issuerInfoMap; } CertificateInfoOrdered CRL::issuerInfoOrdered() const { - return static_cast(context())->props()->issuer; + return static_cast(context())->props()->issuer; } int CRL::number() const { - return static_cast(context())->props()->number; + return static_cast(context())->props()->number; } QDateTime CRL::thisUpdate() const { - return static_cast(context())->props()->thisUpdate; + return static_cast(context())->props()->thisUpdate; } QDateTime CRL::nextUpdate() const { - return static_cast(context())->props()->nextUpdate; + return static_cast(context())->props()->nextUpdate; } QList CRL::revoked() const { - return static_cast(context())->props()->revoked; + return static_cast(context())->props()->revoked; } SignatureAlgorithm CRL::signatureAlgorithm() const { - return static_cast(context())->props()->sigalgo; + return static_cast(context())->props()->sigalgo; } QByteArray CRL::issuerKeyId() const { - return static_cast(context())->props()->issuerId; + return static_cast(context())->props()->issuerId; } QByteArray CRL::toDER() const { - return static_cast(context())->toDER(); + return static_cast(context())->toDER(); } QString CRL::toPEM() const { - return static_cast(context())->toPEM(); + return static_cast(context())->toPEM(); } bool CRL::operator==(const CRL &otherCrl) const { - if(isNull()) - { - if(otherCrl.isNull()) - return true; - else - return false; - } - else if(otherCrl.isNull()) - return false; + if (isNull()) { + if (otherCrl.isNull()) { + return true; + } else { + return false; + } + } else if (otherCrl.isNull()) { + return false; + } - const CRLContext *other = static_cast(otherCrl.context()); - return static_cast(context())->compare(other); + const CRLContext *other = static_cast(otherCrl.context()); + return static_cast(context())->compare(other); } CRL CRL::fromDER(const QByteArray &a, ConvertResult *result, const QString &provider) { - CRL c; - CRLContext *cc = static_cast(getContext("crl", provider)); - ConvertResult r = cc->fromDER(a); - if(result) - *result = r; - if(r == ConvertGood) - c.change(cc); - else - delete cc; - return c; + CRL c; + CRLContext *cc = static_cast(getContext("crl", provider)); + ConvertResult r = cc->fromDER(a); + if (result) { + *result = r; + } + if (r == ConvertGood) { + c.change(cc); + } else { + delete cc; + } + return c; } CRL CRL::fromPEM(const QString &s, ConvertResult *result, const QString &provider) { - CRL c; - CRLContext *cc = static_cast(getContext("crl", provider)); - ConvertResult r = cc->fromPEM(s); - if(result) - *result = r; - if(r == ConvertGood) - c.change(cc); - else - delete cc; - return c; + CRL c; + CRLContext *cc = static_cast(getContext("crl", provider)); + ConvertResult r = cc->fromPEM(s); + if (result) { + *result = r; + } + if (r == ConvertGood) { + c.change(cc); + } else { + delete cc; + } + return c; } CRL CRL::fromPEMFile(const QString &fileName, ConvertResult *result, const QString &provider) { - QString pem; - if(!stringFromFile(fileName, &pem)) - { - if(result) - *result = ErrorFile; - return CRL(); - } - return fromPEM(pem, result, provider); + QString pem; + if (!stringFromFile(fileName, &pem)) { + if (result) { + *result = ErrorFile; + } + return CRL(); + } + return fromPEM(pem, result, provider); } bool CRL::toPEMFile(const QString &fileName) const { - return stringToFile(fileName, toPEM()); + return stringToFile(fileName, toPEM()); } void CRL::change(CRLContext *c) { - Algorithm::change(c); - d->update(static_cast(context())); + Algorithm::change(c); + d->update(static_cast(context())); } //---------------------------------------------------------------------------- @@ -2276,399 +2281,395 @@ // CERTIFICATE / X509 CERTIFICATE static QString readNextPem(QTextStream *ts, bool *isCRL) { - QString pem; - bool crl = false; - bool found = false; - bool done = false; - while(!ts->atEnd()) - { - QString line = ts->readLine(); - if(!found) - { - if(line.startsWith("-----BEGIN ")) - { - if(line.contains("CERTIFICATE")) - { - found = true; - pem += line + '\n'; - crl = false; - } - else if(line.contains("CRL")) - { - found = true; - pem += line + '\n'; - crl = true; - } - } - } - else - { - pem += line + '\n'; - if(line.startsWith("-----END ")) - { - done = true; - break; - } - } - } - if(!done) - return QString(); - if(isCRL) - *isCRL = crl; - return pem; + QString pem; + bool crl = false; + bool found = false; + bool done = false; + while (!ts->atEnd()) { + QString line = ts->readLine(); + if (!found) { + if (line.startsWith("-----BEGIN ")) { + if (line.contains("CERTIFICATE")) { + found = true; + pem += line + '\n'; + crl = false; + } else if (line.contains("CRL")) { + found = true; + pem += line + '\n'; + crl = true; + } + } + } else { + pem += line + '\n'; + if (line.startsWith("-----END ")) { + done = true; + break; + } + } + } + if (!done) { + return QString(); + } + if (isCRL) { + *isCRL = crl; + } + return pem; } class CertificateCollection::Private : public QSharedData { public: - QList certs; - QList crls; + QList certs; + QList crls; }; CertificateCollection::CertificateCollection() -:d(new Private) + : d(new Private) { } CertificateCollection::CertificateCollection(const CertificateCollection &from) -:d(from.d) + : d(from.d) { } CertificateCollection::~CertificateCollection() { } -CertificateCollection & CertificateCollection::operator=(const CertificateCollection &from) +CertificateCollection &CertificateCollection::operator=(const CertificateCollection &from) { - d = from.d; - return *this; + d = from.d; + return *this; } void CertificateCollection::addCertificate(const Certificate &cert) { - d->certs.append(cert); + d->certs.append(cert); } void CertificateCollection::addCRL(const CRL &crl) { - d->crls.append(crl); + d->crls.append(crl); } QList CertificateCollection::certificates() const { - return d->certs; + return d->certs; } QList CertificateCollection::crls() const { - return d->crls; + return d->crls; } void CertificateCollection::append(const CertificateCollection &other) { - d->certs += other.d->certs; - d->crls += other.d->crls; + d->certs += other.d->certs; + d->crls += other.d->crls; } CertificateCollection CertificateCollection::operator+(const CertificateCollection &other) const { - CertificateCollection c = *this; - c.append(other); - return c; + CertificateCollection c = *this; + c.append(other); + return c; } -CertificateCollection & CertificateCollection::operator+=(const CertificateCollection &other) +CertificateCollection &CertificateCollection::operator+=(const CertificateCollection &other) { - append(other); - return *this; + append(other); + return *this; } bool CertificateCollection::canUsePKCS7(const QString &provider) { - return isSupported("certcollection", provider); + return isSupported("certcollection", provider); } bool CertificateCollection::toFlatTextFile(const QString &fileName) { - QFile f(fileName); - if(!f.open(QFile::WriteOnly)) - return false; + QFile f(fileName); + if (!f.open(QFile::WriteOnly)) { + return false; + } - QTextStream ts(&f); - int n; - for(n = 0; n < d->certs.count(); ++n) - ts << d->certs[n].toPEM(); - for(n = 0; n < d->crls.count(); ++n) - ts << d->crls[n].toPEM(); - return true; + QTextStream ts(&f); + int n; + for (n = 0; n < d->certs.count(); ++n) { + ts << d->certs[n].toPEM(); + } + for (n = 0; n < d->crls.count(); ++n) { + ts << d->crls[n].toPEM(); + } + return true; } bool CertificateCollection::toPKCS7File(const QString &fileName, const QString &provider) { - CertCollectionContext *col = static_cast(getContext("certcollection", provider)); + CertCollectionContext *col = static_cast(getContext("certcollection", provider)); - QList cert_list; - QList crl_list; - int n; - for(n = 0; n < d->certs.count(); ++n) - { - CertContext *c = static_cast(d->certs[n].context()); - cert_list += c; - } - for(n = 0; n < d->crls.count(); ++n) - { - CRLContext *c = static_cast(d->crls[n].context()); - crl_list += c; - } + QList cert_list; + QList crl_list; + int n; + for (n = 0; n < d->certs.count(); ++n) { + CertContext *c = static_cast(d->certs[n].context()); + cert_list += c; + } + for (n = 0; n < d->crls.count(); ++n) { + CRLContext *c = static_cast(d->crls[n].context()); + crl_list += c; + } - QByteArray result = col->toPKCS7(cert_list, crl_list); - delete col; + QByteArray result = col->toPKCS7(cert_list, crl_list); + delete col; - return arrayToFile(fileName, result); + return arrayToFile(fileName, result); } CertificateCollection CertificateCollection::fromFlatTextFile(const QString &fileName, ConvertResult *result, const QString &provider) { - QFile f(fileName); - if(!f.open(QFile::ReadOnly)) - { - if(result) - *result = ErrorFile; - return CertificateCollection(); - } - - CertificateCollection certs; - QTextStream ts(&f); - while(1) - { - bool isCRL = false; - QString pem = readNextPem(&ts, &isCRL); - if(pem.isNull()) - break; - if(isCRL) - { - CRL c = CRL::fromPEM(pem, 0, provider); - if(!c.isNull()) - certs.addCRL(c); - } - else - { - Certificate c = Certificate::fromPEM(pem, 0, provider); - if(!c.isNull()) - certs.addCertificate(c); - } - } - - if(result) - *result = ConvertGood; - - return certs; + QFile f(fileName); + if (!f.open(QFile::ReadOnly)) { + if (result) { + *result = ErrorFile; + } + return CertificateCollection(); + } + + CertificateCollection certs; + QTextStream ts(&f); + while (1) { + bool isCRL = false; + QString pem = readNextPem(&ts, &isCRL); + if (pem.isNull()) { + break; + } + if (isCRL) { + CRL c = CRL::fromPEM(pem, 0, provider); + if (!c.isNull()) { + certs.addCRL(c); + } + } else { + Certificate c = Certificate::fromPEM(pem, 0, provider); + if (!c.isNull()) { + certs.addCertificate(c); + } + } + } + + if (result) { + *result = ConvertGood; + } + + return certs; } CertificateCollection CertificateCollection::fromPKCS7File(const QString &fileName, ConvertResult *result, const QString &provider) { - QByteArray der; - if(!arrayFromFile(fileName, &der)) - { - if(result) - *result = ErrorFile; - return CertificateCollection(); - } - - CertificateCollection certs; - - QList cert_list; - QList crl_list; - CertCollectionContext *col = static_cast(getContext("certcollection", provider)); - ConvertResult r = col->fromPKCS7(der, &cert_list, &crl_list); - delete col; - - if(result) - *result = r; - if(r == ConvertGood) - { - int n; - for(n = 0; n < cert_list.count(); ++n) - { - Certificate c; - c.change(cert_list[n]); - certs.addCertificate(c); - } - for(n = 0; n < crl_list.count(); ++n) - { - CRL c; - c.change(crl_list[n]); - certs.addCRL(c); - } - } - return certs; + QByteArray der; + if (!arrayFromFile(fileName, &der)) { + if (result) { + *result = ErrorFile; + } + return CertificateCollection(); + } + + CertificateCollection certs; + + QList cert_list; + QList crl_list; + CertCollectionContext *col = static_cast(getContext("certcollection", provider)); + ConvertResult r = col->fromPKCS7(der, &cert_list, &crl_list); + delete col; + + if (result) { + *result = r; + } + if (r == ConvertGood) { + int n; + for (n = 0; n < cert_list.count(); ++n) { + Certificate c; + c.change(cert_list[n]); + certs.addCertificate(c); + } + for (n = 0; n < crl_list.count(); ++n) { + CRL c; + c.change(crl_list[n]); + certs.addCRL(c); + } + } + return certs; } //---------------------------------------------------------------------------- // CertificateAuthority //---------------------------------------------------------------------------- CertificateAuthority::CertificateAuthority(const Certificate &cert, const PrivateKey &key, const QString &provider) -:Algorithm("ca", provider) + : Algorithm("ca", provider) { - static_cast(context())->setup(*(static_cast(cert.context())), *(static_cast(key.context()))); + static_cast(context())->setup(*(static_cast(cert.context())), *(static_cast(key.context()))); } CertificateAuthority::CertificateAuthority(const CertificateAuthority &from) -:Algorithm(from) + : Algorithm(from) { } CertificateAuthority::~CertificateAuthority() { } -CertificateAuthority & CertificateAuthority::operator=(const CertificateAuthority &from) +CertificateAuthority &CertificateAuthority::operator=(const CertificateAuthority &from) { - Algorithm::operator=(from); - return *this; + Algorithm::operator=(from); + return *this; } Certificate CertificateAuthority::certificate() const { - Certificate c; - c.change(static_cast(context())->certificate()); - return c; + Certificate c; + c.change(static_cast(context())->certificate()); + return c; } Certificate CertificateAuthority::signRequest(const CertificateRequest &req, const QDateTime ¬ValidAfter) const { - Certificate c; - CertContext *cc = static_cast(context())->signRequest(*(static_cast(req.context())), notValidAfter); - if(cc) - c.change(cc); - return c; + Certificate c; + CertContext *cc = static_cast(context())->signRequest(*(static_cast(req.context())), notValidAfter); + if (cc) { + c.change(cc); + } + return c; } CRL CertificateAuthority::createCRL(const QDateTime &nextUpdate) const { - CRL crl; - CRLContext *cc = static_cast(context())->createCRL(nextUpdate); - if(cc) - crl.change(cc); - return crl; + CRL crl; + CRLContext *cc = static_cast(context())->createCRL(nextUpdate); + if (cc) { + crl.change(cc); + } + return crl; } CRL CertificateAuthority::updateCRL(const CRL &crl, const QList &entries, const QDateTime &nextUpdate) const { - CRL new_crl; - CRLContext *cc = static_cast(context())->updateCRL(*(static_cast(crl.context())), entries, nextUpdate); - if(cc) - new_crl.change(cc); - return new_crl; + CRL new_crl; + CRLContext *cc = static_cast(context())->updateCRL(*(static_cast(crl.context())), entries, nextUpdate); + if (cc) { + new_crl.change(cc); + } + return new_crl; } //---------------------------------------------------------------------------- // KeyBundle //---------------------------------------------------------------------------- class KeyBundle::Private : public QSharedData { public: - QString name; - CertificateChain chain; - PrivateKey key; + QString name; + CertificateChain chain; + PrivateKey key; }; KeyBundle::KeyBundle() -:d(new Private) + : d(new Private) { } KeyBundle::KeyBundle(const QString &fileName, const SecureArray &passphrase) -:d(new Private) + : d(new Private) { - *this = fromFile(fileName, passphrase, 0, QString()); + *this = fromFile(fileName, passphrase, 0, QString()); } KeyBundle::KeyBundle(const KeyBundle &from) -:d(from.d) + : d(from.d) { } KeyBundle::~KeyBundle() { } -KeyBundle & KeyBundle::operator=(const KeyBundle &from) +KeyBundle &KeyBundle::operator=(const KeyBundle &from) { - d = from.d; - return *this; + d = from.d; + return *this; } bool KeyBundle::isNull() const { - return d->chain.isEmpty(); + return d->chain.isEmpty(); } QString KeyBundle::name() const { - return d->name; + return d->name; } CertificateChain KeyBundle::certificateChain() const { - return d->chain; + return d->chain; } PrivateKey KeyBundle::privateKey() const { - return d->key; + return d->key; } void KeyBundle::setName(const QString &s) { - d->name = s; + d->name = s; } void KeyBundle::setCertificateChainAndKey(const CertificateChain &c, const PrivateKey &key) { - d->chain = c; - d->key = key; + d->chain = c; + d->key = key; } QByteArray KeyBundle::toArray(const SecureArray &passphrase, const QString &provider) const { - PKCS12Context *pix = static_cast(getContext("pkcs12", provider)); + PKCS12Context *pix = static_cast(getContext("pkcs12", provider)); - QList list; - for(int n = 0; n < d->chain.count(); ++n) - list.append(static_cast(d->chain[n].context())); - QByteArray buf = pix->toPKCS12(d->name, list, *(static_cast(d->key.context())), passphrase); - delete pix; + QList list; + for (int n = 0; n < d->chain.count(); ++n) { + list.append(static_cast(d->chain[n].context())); + } + QByteArray buf = pix->toPKCS12(d->name, list, *(static_cast(d->key.context())), passphrase); + delete pix; - return buf; + return buf; } bool KeyBundle::toFile(const QString &fileName, const SecureArray &passphrase, const QString &provider) const { - return arrayToFile(fileName, toArray(passphrase, provider)); + return arrayToFile(fileName, toArray(passphrase, provider)); } KeyBundle KeyBundle::fromArray(const QByteArray &a, const SecureArray &passphrase, ConvertResult *result, const QString &provider) { - KeyBundle bundle; - get_pkcs12_der(a, QString(), (void *)&a, passphrase, result, provider, &bundle.d->name, &bundle.d->chain, &bundle.d->key); - return bundle; + KeyBundle bundle; + get_pkcs12_der(a, QString(), (void *)&a, passphrase, result, provider, &bundle.d->name, &bundle.d->chain, &bundle.d->key); + return bundle; } KeyBundle KeyBundle::fromFile(const QString &fileName, const SecureArray &passphrase, ConvertResult *result, const QString &provider) { - QByteArray der; - if(!arrayFromFile(fileName, &der)) - { - if(result) - *result = ErrorFile; - return KeyBundle(); - } + QByteArray der; + if (!arrayFromFile(fileName, &der)) { + if (result) { + *result = ErrorFile; + } + return KeyBundle(); + } - KeyBundle bundle; - get_pkcs12_der(der, fileName, 0, passphrase, result, provider, &bundle.d->name, &bundle.d->chain, &bundle.d->key); - return bundle; + KeyBundle bundle; + get_pkcs12_der(der, fileName, 0, passphrase, result, provider, &bundle.d->name, &bundle.d->chain, &bundle.d->key); + return bundle; } //---------------------------------------------------------------------------- @@ -2680,306 +2681,316 @@ PGPKey::PGPKey(const QString &fileName) { - *this = fromFile(fileName, 0, QString()); + *this = fromFile(fileName, 0, QString()); } PGPKey::PGPKey(const PGPKey &from) -:Algorithm(from) + : Algorithm(from) { } PGPKey::~PGPKey() { } -PGPKey & PGPKey::operator=(const PGPKey &from) +PGPKey &PGPKey::operator=(const PGPKey &from) { - Algorithm::operator=(from); - return *this; + Algorithm::operator=(from); + return *this; } bool PGPKey::isNull() const { - return (!context() ? true : false); + return (!context() ? true : false); } QString PGPKey::keyId() const { - return static_cast(context())->props()->keyId; + return static_cast(context())->props()->keyId; } QString PGPKey::primaryUserId() const { - return static_cast(context())->props()->userIds.first(); + return static_cast(context())->props()->userIds.first(); } QStringList PGPKey::userIds() const { - return static_cast(context())->props()->userIds; + return static_cast(context())->props()->userIds; } bool PGPKey::isSecret() const { - return static_cast(context())->props()->isSecret; + return static_cast(context())->props()->isSecret; } QDateTime PGPKey::creationDate() const { - return static_cast(context())->props()->creationDate; + return static_cast(context())->props()->creationDate; } QDateTime PGPKey::expirationDate() const { - return static_cast(context())->props()->expirationDate; + return static_cast(context())->props()->expirationDate; } QString PGPKey::fingerprint() const { - return static_cast(context())->props()->fingerprint; + return static_cast(context())->props()->fingerprint; } bool PGPKey::inKeyring() const { - return static_cast(context())->props()->inKeyring; + return static_cast(context())->props()->inKeyring; } bool PGPKey::isTrusted() const { - return static_cast(context())->props()->isTrusted; + return static_cast(context())->props()->isTrusted; } QByteArray PGPKey::toArray() const { - return static_cast(context())->toBinary(); + return static_cast(context())->toBinary(); } QString PGPKey::toString() const { - return static_cast(context())->toAscii(); + return static_cast(context())->toAscii(); } bool PGPKey::toFile(const QString &fileName) const { - return stringToFile(fileName, toString()); + return stringToFile(fileName, toString()); } PGPKey PGPKey::fromArray(const QByteArray &a, ConvertResult *result, const QString &provider) { - PGPKey k; - PGPKeyContext *kc = static_cast(getContext("pgpkey", provider)); - ConvertResult r = kc->fromBinary(a); - if(result) - *result = r; - if(r == ConvertGood) - k.change(kc); - else - delete kc; - return k; + PGPKey k; + PGPKeyContext *kc = static_cast(getContext("pgpkey", provider)); + ConvertResult r = kc->fromBinary(a); + if (result) { + *result = r; + } + if (r == ConvertGood) { + k.change(kc); + } else { + delete kc; + } + return k; } PGPKey PGPKey::fromString(const QString &s, ConvertResult *result, const QString &provider) { - PGPKey k; - PGPKeyContext *kc = static_cast(getContext("pgpkey", provider)); - ConvertResult r = kc->fromAscii(s); - if(result) - *result = r; - if(r == ConvertGood) - k.change(kc); - else - delete kc; - return k; + PGPKey k; + PGPKeyContext *kc = static_cast(getContext("pgpkey", provider)); + ConvertResult r = kc->fromAscii(s); + if (result) { + *result = r; + } + if (r == ConvertGood) { + k.change(kc); + } else { + delete kc; + } + return k; } PGPKey PGPKey::fromFile(const QString &fileName, ConvertResult *result, const QString &provider) { - QString str; - if(!stringFromFile(fileName, &str)) - { - if(result) - *result = ErrorFile; - return PGPKey(); - } - return fromString(str, result, provider); + QString str; + if (!stringFromFile(fileName, &str)) { + if (result) { + *result = ErrorFile; + } + return PGPKey(); + } + return fromString(str, result, provider); } //---------------------------------------------------------------------------- // KeyLoader //---------------------------------------------------------------------------- class KeyLoaderThread : public QThread { - Q_OBJECT + Q_OBJECT public: - enum Type { PKPEMFile, PKPEM, PKDER, KBDERFile, KBDER }; - - class In - { - public: - Type type; - QString fileName, pem; - SecureArray der; - QByteArray kbder; - }; - - class Out - { - public: - ConvertResult convertResult; - PrivateKey privateKey; - KeyBundle keyBundle; - }; - - In in; - Out out; - - KeyLoaderThread(QObject *parent = 0) : QThread(parent) - { - } + enum Type { PKPEMFile, PKPEM, PKDER, KBDERFile, KBDER }; + + class In + { + public: + Type type; + QString fileName, pem; + SecureArray der; + QByteArray kbder; + }; + + class Out + { + public: + ConvertResult convertResult; + PrivateKey privateKey; + KeyBundle keyBundle; + }; + + In in; + Out out; + + KeyLoaderThread(QObject *parent = 0) : QThread(parent) + { + } protected: - virtual void run() - { - if(in.type == PKPEMFile) - out.privateKey = PrivateKey::fromPEMFile(in.fileName, SecureArray(), &out.convertResult); - else if(in.type == PKPEM) - out.privateKey = PrivateKey::fromPEM(in.pem, SecureArray(), &out.convertResult); - else if(in.type == PKDER) - out.privateKey = PrivateKey::fromDER(in.der, SecureArray(), &out.convertResult); - else if(in.type == KBDERFile) - out.keyBundle = KeyBundle::fromFile(in.fileName, SecureArray(), &out.convertResult); - else if(in.type == KBDER) - out.keyBundle = KeyBundle::fromArray(in.kbder, SecureArray(), &out.convertResult); - } + virtual void run() + { + if (in.type == PKPEMFile) { + out.privateKey = PrivateKey::fromPEMFile(in.fileName, SecureArray(), &out.convertResult); + } else if (in.type == PKPEM) { + out.privateKey = PrivateKey::fromPEM(in.pem, SecureArray(), &out.convertResult); + } else if (in.type == PKDER) { + out.privateKey = PrivateKey::fromDER(in.der, SecureArray(), &out.convertResult); + } else if (in.type == KBDERFile) { + out.keyBundle = KeyBundle::fromFile(in.fileName, SecureArray(), &out.convertResult); + } else if (in.type == KBDER) { + out.keyBundle = KeyBundle::fromArray(in.kbder, SecureArray(), &out.convertResult); + } + } }; class KeyLoader::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - KeyLoader *q; - - bool active; - KeyLoaderThread *thread; - KeyLoaderThread::In in; - KeyLoaderThread::Out out; - - Private(KeyLoader *_q) : QObject(_q), q(_q) - { - active = false; - } - - void reset() - { - in = KeyLoaderThread::In(); - out = KeyLoaderThread::Out(); - } - - void start() - { - active = true; - thread = new KeyLoaderThread(this); - // used queued for signal-safety - connect(thread, SIGNAL(finished()), SLOT(thread_finished()), Qt::QueuedConnection); - thread->in = in; - thread->start(); - } + KeyLoader *q; + + bool active; + KeyLoaderThread *thread; + KeyLoaderThread::In in; + KeyLoaderThread::Out out; + + Private(KeyLoader *_q) : QObject(_q), q(_q) + { + active = false; + } + + void reset() + { + in = KeyLoaderThread::In(); + out = KeyLoaderThread::Out(); + } + + void start() + { + active = true; + thread = new KeyLoaderThread(this); + // used queued for signal-safety + connect(thread, SIGNAL(finished()), SLOT(thread_finished()), Qt::QueuedConnection); + thread->in = in; + thread->start(); + } private slots: - void thread_finished() - { - out = thread->out; - delete thread; - thread = 0; - active = false; - - emit q->finished(); - } + void thread_finished() + { + out = thread->out; + delete thread; + thread = 0; + active = false; + + emit q->finished(); + } }; KeyLoader::KeyLoader(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); + d = new Private(this); } KeyLoader::~KeyLoader() { - delete d; + delete d; } void KeyLoader::loadPrivateKeyFromPEMFile(const QString &fileName) { - Q_ASSERT(!d->active); - if(d->active) - return; + Q_ASSERT(!d->active); + if (d->active) { + return; + } - d->reset(); - d->in.type = KeyLoaderThread::PKPEMFile; - d->in.fileName = fileName; - d->start(); + d->reset(); + d->in.type = KeyLoaderThread::PKPEMFile; + d->in.fileName = fileName; + d->start(); } void KeyLoader::loadPrivateKeyFromPEM(const QString &s) { - Q_ASSERT(!d->active); - if(d->active) - return; + Q_ASSERT(!d->active); + if (d->active) { + return; + } - d->reset(); - d->in.type = KeyLoaderThread::PKPEM; - d->in.pem = s; - d->start(); + d->reset(); + d->in.type = KeyLoaderThread::PKPEM; + d->in.pem = s; + d->start(); } void KeyLoader::loadPrivateKeyFromDER(const SecureArray &a) { - Q_ASSERT(!d->active); - if(d->active) - return; + Q_ASSERT(!d->active); + if (d->active) { + return; + } - d->reset(); - d->in.type = KeyLoaderThread::PKDER; - d->in.der = a; - d->start(); + d->reset(); + d->in.type = KeyLoaderThread::PKDER; + d->in.der = a; + d->start(); } void KeyLoader::loadKeyBundleFromFile(const QString &fileName) { - Q_ASSERT(!d->active); - if(d->active) - return; + Q_ASSERT(!d->active); + if (d->active) { + return; + } - d->reset(); - d->in.type = KeyLoaderThread::KBDERFile; - d->in.fileName = fileName; - d->start(); + d->reset(); + d->in.type = KeyLoaderThread::KBDERFile; + d->in.fileName = fileName; + d->start(); } void KeyLoader::loadKeyBundleFromArray(const QByteArray &a) { - Q_ASSERT(!d->active); - if(d->active) - return; + Q_ASSERT(!d->active); + if (d->active) { + return; + } - d->reset(); - d->in.type = KeyLoaderThread::KBDERFile; - d->in.kbder = a; - d->start(); + d->reset(); + d->in.type = KeyLoaderThread::KBDERFile; + d->in.kbder = a; + d->start(); } ConvertResult KeyLoader::convertResult() const { - return d->out.convertResult; + return d->out.convertResult; } PrivateKey KeyLoader::privateKey() const { - return d->out.privateKey; + return d->out.privateKey; } KeyBundle KeyLoader::keyBundle() const { - return d->out.keyBundle; + return d->out.keyBundle; } } diff --git a/src/qca_core.cpp b/src/qca_core.cpp --- a/src/qca_core.cpp +++ b/src/qca_core.cpp @@ -43,30 +43,31 @@ int qcaVersion() { - return QCA_VERSION; + return QCA_VERSION; } const char *qcaVersionStr() { - return QCA_VERSION_STR; + return QCA_VERSION_STR; } int qcaMajorVersion() { - return QCA_MAJOR_VERSION; + return QCA_MAJOR_VERSION; } int qcaMinorVersion() { - return QCA_MINOR_VERSION; + return QCA_MINOR_VERSION; } int qcaPatchVersion() { - return QCA_PATCH_VERSION; + return QCA_PATCH_VERSION; } -namespace QCA { +namespace QCA +{ // from qca_tools bool botan_init(int prealloc, bool mmap); @@ -81,837 +82,872 @@ class Global { public: - int refs; - bool secmem; - bool loaded; - bool first_scan; - QString app_name; - QMutex name_mutex; - ProviderManager *manager; - QMutex scan_mutex; - Random *rng; - QMutex rng_mutex; - Logger *logger; - QVariantMap properties; - QMutex prop_mutex; - QMap config; - QMutex config_mutex; - QMutex logger_mutex; - - Global() - { - refs = 0; - secmem = false; - loaded = false; - first_scan = false; - rng = 0; - logger = 0; - manager = new ProviderManager; - } - - ~Global() - { - KeyStoreManager::shutdown(); - delete rng; - rng = 0; - delete manager; - manager = 0; - delete logger; - logger = 0; - } - - void ensure_loaded() - { - // probably we shouldn't overload scan mutex, or else rename it - QMutexLocker locker(&scan_mutex); - if(!loaded) - { - loaded = true; - manager->setDefault(create_default_provider()); // manager owns it - } - } - - bool ensure_first_scan() - { - scan_mutex.lock(); - if(!first_scan) - { - first_scan = true; - manager->scan(); - scan_mutex.unlock(); - return true; - } - scan_mutex.unlock(); - return false; - } - - void scan() - { - scan_mutex.lock(); - first_scan = true; - manager->scan(); - scan_mutex.unlock(); - } - - void ksm_scan() - { - KeyStoreManager::scan(); - } - - Logger *get_logger() - { - QMutexLocker locker(&logger_mutex); - if(!logger) - { - logger = new Logger; - - // needed so deinit may delete the logger regardless - // of what thread the logger was created from - logger->moveToThread(0); - } - return logger; - } - - void unloadAllPlugins() - { - KeyStoreManager::shutdown(); - - // if the global_rng was owned by a plugin, then delete it - rng_mutex.lock(); - if(rng && (rng->provider() != manager->find("default"))) - { - delete rng; - rng = 0; - } - rng_mutex.unlock(); - - manager->unloadAll(); - } + int refs; + bool secmem; + bool loaded; + bool first_scan; + QString app_name; + QMutex name_mutex; + ProviderManager *manager; + QMutex scan_mutex; + Random *rng; + QMutex rng_mutex; + Logger *logger; + QVariantMap properties; + QMutex prop_mutex; + QMap config; + QMutex config_mutex; + QMutex logger_mutex; + + Global() + { + refs = 0; + secmem = false; + loaded = false; + first_scan = false; + rng = 0; + logger = 0; + manager = new ProviderManager; + } + + ~Global() + { + KeyStoreManager::shutdown(); + delete rng; + rng = 0; + delete manager; + manager = 0; + delete logger; + logger = 0; + } + + void ensure_loaded() + { + // probably we shouldn't overload scan mutex, or else rename it + QMutexLocker locker(&scan_mutex); + if (!loaded) { + loaded = true; + manager->setDefault(create_default_provider()); // manager owns it + } + } + + bool ensure_first_scan() + { + scan_mutex.lock(); + if (!first_scan) { + first_scan = true; + manager->scan(); + scan_mutex.unlock(); + return true; + } + scan_mutex.unlock(); + return false; + } + + void scan() + { + scan_mutex.lock(); + first_scan = true; + manager->scan(); + scan_mutex.unlock(); + } + + void ksm_scan() + { + KeyStoreManager::scan(); + } + + Logger *get_logger() + { + QMutexLocker locker(&logger_mutex); + if (!logger) { + logger = new Logger; + + // needed so deinit may delete the logger regardless + // of what thread the logger was created from + logger->moveToThread(0); + } + return logger; + } + + void unloadAllPlugins() + { + KeyStoreManager::shutdown(); + + // if the global_rng was owned by a plugin, then delete it + rng_mutex.lock(); + if (rng && (rng->provider() != manager->find("default"))) { + delete rng; + rng = 0; + } + rng_mutex.unlock(); + + manager->unloadAll(); + } }; Q_GLOBAL_STATIC(QMutex, global_mutex) static Global *global = 0; static bool features_have(const QStringList &have, const QStringList &want) { - foreach(const QString &i, want) - { - if(!have.contains(i)) - return false; - } - return true; + foreach (const QString &i, want) { + if (!have.contains(i)) { + return false; + } + } + return true; } void init(MemoryMode mode, int prealloc) { - QMutexLocker locker(global_mutex()); - if(global) - { - ++(global->refs); - return; - } - - bool allow_mmap_fallback = false; - bool drop_root = false; - if(mode == Practical) - { - allow_mmap_fallback = true; - drop_root = true; - } - else if(mode == Locking) - drop_root = true; - - bool secmem = botan_init(prealloc, allow_mmap_fallback); - - if(drop_root) - { + QMutexLocker locker(global_mutex()); + if (global) { + ++(global->refs); + return; + } + + bool allow_mmap_fallback = false; + bool drop_root = false; + if (mode == Practical) { + allow_mmap_fallback = true; + drop_root = true; + } else if (mode == Locking) { + drop_root = true; + } + + bool secmem = botan_init(prealloc, allow_mmap_fallback); + + if (drop_root) { #ifdef Q_OS_UNIX - setuid(getuid()); + setuid(getuid()); #endif - } - - global = new Global; - global->secmem = secmem; - ++(global->refs); - - // for maximum setuid safety, qca should be initialized before qapp: - // - // int main(int argc, char **argv) - // { - // QCA::Initializer init; - // QCoreApplication app(argc, argv); - // return 0; - // } - // - // however, the above code has the unfortunate side-effect of causing - // qapp to deinit before qca, which can cause problems with any - // plugins that have active objects (notably KeyStore). we'll use a - // post routine to force qca to deinit first. - qAddPostRoutine(deinit); + } + + global = new Global; + global->secmem = secmem; + ++(global->refs); + + // for maximum setuid safety, qca should be initialized before qapp: + // + // int main(int argc, char **argv) + // { + // QCA::Initializer init; + // QCoreApplication app(argc, argv); + // return 0; + // } + // + // however, the above code has the unfortunate side-effect of causing + // qapp to deinit before qca, which can cause problems with any + // plugins that have active objects (notably KeyStore). we'll use a + // post routine to force qca to deinit first. + qAddPostRoutine(deinit); } void init() { - init(Practical, 64); + init(Practical, 64); } void deinit() { - QMutexLocker locker(global_mutex()); - if(!global) - return; - --(global->refs); - if(global->refs == 0) - { - // In order to maintain symmetry with the init() function, remove the - // post routine from QCoreApplication. This is needed in case when the - // QCA library is unloaded before QCoreApplication instance completes: - // QCoreApplication d-tor would try to execute the deinit() function, - // which would no longer be there. - // Note that this function is documented only in Qt 5.3 and later, but - // it has been present since ancient times with the same semantics. - qRemovePostRoutine(deinit); - - delete global; - global = 0; - botan_deinit(); - } + QMutexLocker locker(global_mutex()); + if (!global) { + return; + } + --(global->refs); + if (global->refs == 0) { + // In order to maintain symmetry with the init() function, remove the + // post routine from QCoreApplication. This is needed in case when the + // QCA library is unloaded before QCoreApplication instance completes: + // QCoreApplication d-tor would try to execute the deinit() function, + // which would no longer be there. + // Note that this function is documented only in Qt 5.3 and later, but + // it has been present since ancient times with the same semantics. + qRemovePostRoutine(deinit); + + delete global; + global = 0; + botan_deinit(); + } } static bool global_check() { - Q_ASSERT(global); - if(!global) - return false; - return true; + Q_ASSERT(global); + if (!global) { + return false; + } + return true; } static bool global_check_load() { - Q_ASSERT(global); - if(!global) - return false; - global->ensure_loaded(); - return true; + Q_ASSERT(global); + if (!global) { + return false; + } + global->ensure_loaded(); + return true; } QMutex *global_random_mutex() { - return &global->rng_mutex; + return &global->rng_mutex; } Random *global_random() { - if(!global->rng) - global->rng = new Random; - return global->rng; + if (!global->rng) { + global->rng = new Random; + } + return global->rng; } bool haveSecureMemory() { - if(!global_check()) - return false; + if (!global_check()) { + return false; + } - return global->secmem; + return global->secmem; } bool haveSecureRandom() { - if(!global_check_load()) - return false; + if (!global_check_load()) { + return false; + } - QMutexLocker locker(global_random_mutex()); - if(global_random()->provider()->name() != "default") - return true; + QMutexLocker locker(global_random_mutex()); + if (global_random()->provider()->name() != "default") { + return true; + } - return false; + return false; } bool isSupported(const QStringList &features, const QString &provider) { - if(!global_check_load()) - return false; - - // single - if(!provider.isEmpty()) - { - Provider *p = global->manager->find(provider); - if(!p) - { - // ok, try scanning for new stuff - global->scan(); - p = global->manager->find(provider); - } - - if(p && features_have(p->features(), features)) - return true; - } - // all - else - { - if(features_have(global->manager->allFeatures(), features)) - return true; - - global->manager->appendDiagnosticText(QString("Scanning to find features: %1\n").arg(features.join(" "))); - - // ok, try scanning for new stuff - global->scan(); - - if(features_have(global->manager->allFeatures(), features)) - return true; - } - return false; + if (!global_check_load()) { + return false; + } + + // single + if (!provider.isEmpty()) { + Provider *p = global->manager->find(provider); + if (!p) { + // ok, try scanning for new stuff + global->scan(); + p = global->manager->find(provider); + } + + if (p && features_have(p->features(), features)) { + return true; + } + } + // all + else { + if (features_have(global->manager->allFeatures(), features)) { + return true; + } + + global->manager->appendDiagnosticText(QString("Scanning to find features: %1\n").arg(features.join(" "))); + + // ok, try scanning for new stuff + global->scan(); + + if (features_have(global->manager->allFeatures(), features)) { + return true; + } + } + return false; } bool isSupported(const char *features, const QString &provider) { - return isSupported(QString(features).split(',', QString::SkipEmptyParts), provider); + return isSupported(QString(features).split(',', QString::SkipEmptyParts), provider); } QStringList supportedFeatures() { - if(!global_check_load()) - return QStringList(); + if (!global_check_load()) { + return QStringList(); + } - // query all features - global->scan(); - return global->manager->allFeatures(); + // query all features + global->scan(); + return global->manager->allFeatures(); } QStringList defaultFeatures() { - if(!global_check_load()) - return QStringList(); + if (!global_check_load()) { + return QStringList(); + } - return global->manager->find("default")->features(); + return global->manager->find("default")->features(); } ProviderList providers() { - if(!global_check_load()) - return ProviderList(); + if (!global_check_load()) { + return ProviderList(); + } - global->ensure_first_scan(); + global->ensure_first_scan(); - return global->manager->providers(); + return global->manager->providers(); } bool insertProvider(Provider *p, int priority) { - if(!global_check_load()) - return false; + if (!global_check_load()) { + return false; + } - global->ensure_first_scan(); + global->ensure_first_scan(); - return global->manager->add(p, priority); + return global->manager->add(p, priority); } bool unloadProvider(const QString &name) { - if(!global_check_load()) - return false; + if (!global_check_load()) { + return false; + } - global->ensure_first_scan(); + global->ensure_first_scan(); - return global->manager->unload(name); + return global->manager->unload(name); } void setProviderPriority(const QString &name, int priority) { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - global->ensure_first_scan(); + global->ensure_first_scan(); - global->manager->changePriority(name, priority); + global->manager->changePriority(name, priority); } int providerPriority(const QString &name) { - if(!global_check_load()) - return -1; + if (!global_check_load()) { + return -1; + } - global->ensure_first_scan(); + global->ensure_first_scan(); - return global->manager->getPriority(name); + return global->manager->getPriority(name); } Provider *findProvider(const QString &name) { - if(!global_check_load()) - return 0; + if (!global_check_load()) { + return 0; + } - global->ensure_first_scan(); + global->ensure_first_scan(); - return global->manager->find(name); + return global->manager->find(name); } Provider *defaultProvider() { - if(!global_check_load()) - return 0; + if (!global_check_load()) { + return 0; + } - return global->manager->find("default"); + return global->manager->find("default"); } QStringList pluginPaths() { - QStringList paths; + QStringList paths; #ifndef DEVELOPER_MODE - const QString qcaPluginPath = qgetenv("QCA_PLUGIN_PATH"); - if (!qcaPluginPath.isEmpty()) - { + const QString qcaPluginPath = qgetenv("QCA_PLUGIN_PATH"); + if (!qcaPluginPath.isEmpty()) { #ifdef Q_OS_WIN - QLatin1Char pathSep(';'); + QLatin1Char pathSep(';'); #else - QLatin1Char pathSep(':'); + QLatin1Char pathSep(':'); #endif - foreach (const QString &path, qcaPluginPath.split(pathSep)) - { - QString canonicalPath = QDir(path).canonicalPath(); - if (!canonicalPath.isEmpty()) - paths << canonicalPath; - } - - } - paths += QCoreApplication::libraryPaths(); + foreach (const QString &path, qcaPluginPath.split(pathSep)) { + QString canonicalPath = QDir(path).canonicalPath(); + if (!canonicalPath.isEmpty()) { + paths << canonicalPath; + } + } + + } + paths += QCoreApplication::libraryPaths(); #endif - // In developer mode load plugins only from buildtree. - // In regular mode QCA_PLUGIN_PATH is path where plugins was installed - paths << QDir(QCA_PLUGIN_PATH).canonicalPath(); + // In developer mode load plugins only from buildtree. + // In regular mode QCA_PLUGIN_PATH is path where plugins was installed + paths << QDir(QCA_PLUGIN_PATH).canonicalPath(); #ifndef DEVELOPER_MODE - paths.removeDuplicates(); + paths.removeDuplicates(); #endif - // No empty strings - paths.removeAll(QString()); - return paths; + // No empty strings + paths.removeAll(QString()); + return paths; } void scanForPlugins() { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - global->scan(); - global->ksm_scan(); + global->scan(); + global->ksm_scan(); } void unloadAllPlugins() { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - global->unloadAllPlugins(); + global->unloadAllPlugins(); } QString pluginDiagnosticText() { - if(!global_check_load()) - return QString(); + if (!global_check_load()) { + return QString(); + } - return global->manager->diagnosticText(); + return global->manager->diagnosticText(); } void clearPluginDiagnosticText() { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - global->manager->clearDiagnosticText(); + global->manager->clearDiagnosticText(); } void appendPluginDiagnosticText(const QString &text) { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - global->manager->appendDiagnosticText(text); + global->manager->appendDiagnosticText(text); } void setProperty(const QString &name, const QVariant &value) { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - QMutexLocker locker(&global->prop_mutex); + QMutexLocker locker(&global->prop_mutex); - global->properties[name] = value; + global->properties[name] = value; } QVariant getProperty(const QString &name) { - if(!global_check_load()) - return QVariant(); + if (!global_check_load()) { + return QVariant(); + } - QMutexLocker locker(&global->prop_mutex); + QMutexLocker locker(&global->prop_mutex); - return global->properties.value(name); + return global->properties.value(name); } static bool configIsValid(const QVariantMap &config) { - if(!config.contains("formtype")) - return false; - QMapIterator it(config); - while(it.hasNext()) - { - it.next(); - const QVariant &v = it.value(); - if(v.type() != QVariant::String && v.type() != QVariant::Int && v.type() != QVariant::Bool) - return false; - } - return true; + if (!config.contains("formtype")) { + return false; + } + QMapIterator it(config); + while (it.hasNext()) { + it.next(); + const QVariant &v = it.value(); + if (v.type() != QVariant::String && v.type() != QVariant::Int && v.type() != QVariant::Bool) { + return false; + } + } + return true; } static QVariantMap readConfig(const QString &name) { - QSettings settings("Affinix", "QCA2"); - settings.beginGroup("ProviderConfig"); - QStringList providerNames = settings.value("providerNames").toStringList(); - if(!providerNames.contains(name)) - return QVariantMap(); + QSettings settings("Affinix", "QCA2"); + settings.beginGroup("ProviderConfig"); + QStringList providerNames = settings.value("providerNames").toStringList(); + if (!providerNames.contains(name)) { + return QVariantMap(); + } - settings.beginGroup(name); - QStringList keys = settings.childKeys(); - QVariantMap map; - foreach(const QString &key, keys) - map[key] = settings.value(key); - settings.endGroup(); + settings.beginGroup(name); + QStringList keys = settings.childKeys(); + QVariantMap map; + foreach (const QString &key, keys) { + map[key] = settings.value(key); + } + settings.endGroup(); - if(!configIsValid(map)) - return QVariantMap(); - return map; + if (!configIsValid(map)) { + return QVariantMap(); + } + return map; } static bool writeConfig(const QString &name, const QVariantMap &config, bool systemWide = false) { - QSettings settings(QSettings::NativeFormat, systemWide ? QSettings::SystemScope : QSettings::UserScope, "Affinix", "QCA2"); - settings.beginGroup("ProviderConfig"); + QSettings settings(QSettings::NativeFormat, systemWide ? QSettings::SystemScope : QSettings::UserScope, "Affinix", "QCA2"); + settings.beginGroup("ProviderConfig"); - // version - settings.setValue("version", 2); + // version + settings.setValue("version", 2); - // add the entry if needed - QStringList providerNames = settings.value("providerNames").toStringList(); - if(!providerNames.contains(name)) - providerNames += name; - settings.setValue("providerNames", providerNames); + // add the entry if needed + QStringList providerNames = settings.value("providerNames").toStringList(); + if (!providerNames.contains(name)) { + providerNames += name; + } + settings.setValue("providerNames", providerNames); - settings.beginGroup(name); - QMapIterator it(config); - while(it.hasNext()) - { - it.next(); - settings.setValue(it.key(), it.value()); - } - settings.endGroup(); + settings.beginGroup(name); + QMapIterator it(config); + while (it.hasNext()) { + it.next(); + settings.setValue(it.key(), it.value()); + } + settings.endGroup(); - if(settings.status() == QSettings::NoError) - return true; - return false; + if (settings.status() == QSettings::NoError) { + return true; + } + return false; } void setProviderConfig(const QString &name, const QVariantMap &config) { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - if(!configIsValid(config)) - return; + if (!configIsValid(config)) { + return; + } - global->config_mutex.lock(); - global->config[name] = config; - global->config_mutex.unlock(); + global->config_mutex.lock(); + global->config[name] = config; + global->config_mutex.unlock(); - Provider *p = findProvider(name); - if(p) - p->configChanged(config); + Provider *p = findProvider(name); + if (p) { + p->configChanged(config); + } } QVariantMap getProviderConfig(const QString &name) { - if(!global_check_load()) - return QVariantMap(); + if (!global_check_load()) { + return QVariantMap(); + } - QVariantMap conf; + QVariantMap conf; - global->config_mutex.lock(); + global->config_mutex.lock(); - // try loading from persistent storage - conf = readConfig(name); + // try loading from persistent storage + conf = readConfig(name); - // if not, load the one from memory - if(conf.isEmpty()) - conf = global->config.value(name); + // if not, load the one from memory + if (conf.isEmpty()) { + conf = global->config.value(name); + } - global->config_mutex.unlock(); + global->config_mutex.unlock(); - // if provider doesn't exist or doesn't have a valid config form, - // use the config we loaded - Provider *p = findProvider(name); - if(!p) - return conf; - QVariantMap pconf = p->defaultConfig(); - if(!configIsValid(pconf)) - return conf; + // if provider doesn't exist or doesn't have a valid config form, + // use the config we loaded + Provider *p = findProvider(name); + if (!p) { + return conf; + } + QVariantMap pconf = p->defaultConfig(); + if (!configIsValid(pconf)) { + return conf; + } - // if the config loaded was empty, use the provider's config - if(conf.isEmpty()) - return pconf; + // if the config loaded was empty, use the provider's config + if (conf.isEmpty()) { + return pconf; + } - // if the config formtype doesn't match the provider's formtype, - // then use the provider's - if(pconf["formtype"] != conf["formtype"]) - return pconf; + // if the config formtype doesn't match the provider's formtype, + // then use the provider's + if (pconf["formtype"] != conf["formtype"]) { + return pconf; + } - // otherwise, use the config loaded - return conf; + // otherwise, use the config loaded + return conf; } void saveProviderConfig(const QString &name) { - if(!global_check_load()) - return; + if (!global_check_load()) { + return; + } - QMutexLocker locker(&global->config_mutex); + QMutexLocker locker(&global->config_mutex); - QVariantMap conf = global->config.value(name); - if(conf.isEmpty()) - return; + QVariantMap conf = global->config.value(name); + if (conf.isEmpty()) { + return; + } - writeConfig(name, conf); + writeConfig(name, conf); } QVariantMap getProviderConfig_internal(Provider *p) { - QVariantMap conf; - QString name = p->name(); + QVariantMap conf; + QString name = p->name(); - global->config_mutex.lock(); + global->config_mutex.lock(); - // try loading from persistent storage - conf = readConfig(name); + // try loading from persistent storage + conf = readConfig(name); - // if not, load the one from memory - if(conf.isEmpty()) - conf = global->config.value(name); + // if not, load the one from memory + if (conf.isEmpty()) { + conf = global->config.value(name); + } - global->config_mutex.unlock(); + global->config_mutex.unlock(); - // if provider doesn't exist or doesn't have a valid config form, - // use the config we loaded - QVariantMap pconf = p->defaultConfig(); - if(!configIsValid(pconf)) - return conf; + // if provider doesn't exist or doesn't have a valid config form, + // use the config we loaded + QVariantMap pconf = p->defaultConfig(); + if (!configIsValid(pconf)) { + return conf; + } - // if the config loaded was empty, use the provider's config - if(conf.isEmpty()) - return pconf; + // if the config loaded was empty, use the provider's config + if (conf.isEmpty()) { + return pconf; + } - // if the config formtype doesn't match the provider's formtype, - // then use the provider's - if(pconf["formtype"] != conf["formtype"]) - return pconf; + // if the config formtype doesn't match the provider's formtype, + // then use the provider's + if (pconf["formtype"] != conf["formtype"]) { + return pconf; + } - // otherwise, use the config loaded - return conf; + // otherwise, use the config loaded + return conf; } QString globalRandomProvider() { - QMutexLocker locker(global_random_mutex()); - return global_random()->provider()->name(); + QMutexLocker locker(global_random_mutex()); + return global_random()->provider()->name(); } void setGlobalRandomProvider(const QString &provider) { - QMutexLocker locker(global_random_mutex()); - delete global->rng; - global->rng = new Random(provider); + QMutexLocker locker(global_random_mutex()); + delete global->rng; + global->rng = new Random(provider); } Logger *logger() { - return global->get_logger(); + return global->get_logger(); } bool haveSystemStore() { - // ensure the system store is loaded - KeyStoreManager::start("default"); - KeyStoreManager ksm; - ksm.waitForBusyFinished(); + // ensure the system store is loaded + KeyStoreManager::start("default"); + KeyStoreManager ksm; + ksm.waitForBusyFinished(); - QStringList list = ksm.keyStores(); - for(int n = 0; n < list.count(); ++n) - { - KeyStore ks(list[n], &ksm); - if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates()) - return true; - } - return false; + QStringList list = ksm.keyStores(); + for (int n = 0; n < list.count(); ++n) { + KeyStore ks(list[n], &ksm); + if (ks.type() == KeyStore::System && ks.holdsTrustedCertificates()) { + return true; + } + } + return false; } CertificateCollection systemStore() { - // ensure the system store is loaded - KeyStoreManager::start("default"); - KeyStoreManager ksm; - ksm.waitForBusyFinished(); - - CertificateCollection col; - QStringList list = ksm.keyStores(); - for(int n = 0; n < list.count(); ++n) - { - KeyStore ks(list[n], &ksm); - - // system store - if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates()) - { - // extract contents - QList entries = ks.entryList(); - for(int i = 0; i < entries.count(); ++i) - { - if(entries[i].type() == KeyStoreEntry::TypeCertificate) - col.addCertificate(entries[i].certificate()); - else if(entries[i].type() == KeyStoreEntry::TypeCRL) - col.addCRL(entries[i].crl()); - } - break; - } - } - return col; + // ensure the system store is loaded + KeyStoreManager::start("default"); + KeyStoreManager ksm; + ksm.waitForBusyFinished(); + + CertificateCollection col; + QStringList list = ksm.keyStores(); + for (int n = 0; n < list.count(); ++n) { + KeyStore ks(list[n], &ksm); + + // system store + if (ks.type() == KeyStore::System && ks.holdsTrustedCertificates()) { + // extract contents + QList entries = ks.entryList(); + for (int i = 0; i < entries.count(); ++i) { + if (entries[i].type() == KeyStoreEntry::TypeCertificate) { + col.addCertificate(entries[i].certificate()); + } else if (entries[i].type() == KeyStoreEntry::TypeCRL) { + col.addCRL(entries[i].crl()); + } + } + break; + } + } + return col; } QString appName() { - if(!global_check()) - return QString(); + if (!global_check()) { + return QString(); + } - QMutexLocker locker(&global->name_mutex); + QMutexLocker locker(&global->name_mutex); - return global->app_name; + return global->app_name; } void setAppName(const QString &s) { - if(!global_check()) - return; + if (!global_check()) { + return; + } - QMutexLocker locker(&global->name_mutex); + QMutexLocker locker(&global->name_mutex); - global->app_name = s; + global->app_name = s; } QString arrayToHex(const QByteArray &a) { - return Hex().arrayToString(a); + return Hex().arrayToString(a); } QByteArray hexToArray(const QString &str) { - return Hex().stringToArray(str).toByteArray(); + return Hex().stringToArray(str).toByteArray(); } QString arrayToBase64(const QByteArray &a) { - return Base64().arrayToString(a); + return Base64().arrayToString(a); } QByteArray base64ToArray(const QString &base64String) { - return Base64().stringToArray(base64String).toByteArray(); + return Base64().stringToArray(base64String).toByteArray(); } static Provider *getProviderForType(const QString &type, const QString &provider) { - Provider *p = 0; - bool scanned = global->ensure_first_scan(); - if(!provider.isEmpty()) - { - // try using specific provider - p = global->manager->findFor(provider, type); - if(!p && !scanned) - { - // maybe this provider is new, so scan and try again - global->scan(); - scanned = true; - p = global->manager->findFor(provider, type); - } - } - if(!p) - { - // try using some other provider - p = global->manager->findFor(QString(), type); - - // note: we used to rescan if no provider was found or if - // the only found provider was 'default'. now we only - // rescan if no provider was found. this optimizes lookups - // for features that are in the default provider (such as - // 'sha1') when no other plugin is available. the drawback - // is that if a plugin is installed later during runtime, - // then it won't be picked up without restarting the - // application or manually calling QCA::scanForPlugins. - //if((!p || p->name() == "default") && !scanned) - if(!p && !scanned) - { - // maybe there are new providers, so scan and try again - // before giving up or using default - global->scan(); - scanned = true; - p = global->manager->findFor(QString(), type); - } - } - - return p; + Provider *p = 0; + bool scanned = global->ensure_first_scan(); + if (!provider.isEmpty()) { + // try using specific provider + p = global->manager->findFor(provider, type); + if (!p && !scanned) { + // maybe this provider is new, so scan and try again + global->scan(); + scanned = true; + p = global->manager->findFor(provider, type); + } + } + if (!p) { + // try using some other provider + p = global->manager->findFor(QString(), type); + + // note: we used to rescan if no provider was found or if + // the only found provider was 'default'. now we only + // rescan if no provider was found. this optimizes lookups + // for features that are in the default provider (such as + // 'sha1') when no other plugin is available. the drawback + // is that if a plugin is installed later during runtime, + // then it won't be picked up without restarting the + // application or manually calling QCA::scanForPlugins. + //if((!p || p->name() == "default") && !scanned) + if (!p && !scanned) { + // maybe there are new providers, so scan and try again + // before giving up or using default + global->scan(); + scanned = true; + p = global->manager->findFor(QString(), type); + } + } + + return p; } static inline Provider::Context *doCreateContext(Provider *p, const QString &type) { - return p->createContext(type); + return p->createContext(type); } Provider::Context *getContext(const QString &type, const QString &provider) { - if(!global_check_load()) - return 0; + if (!global_check_load()) { + return 0; + } - Provider *p; - { - p = getProviderForType(type, provider); - if(!p) - return 0; - } + Provider *p; + { + p = getProviderForType(type, provider); + if (!p) { + return 0; + } + } - return doCreateContext(p, type); + return doCreateContext(p, type); } Provider::Context *getContext(const QString &type, Provider *_p) { - if(!global_check_load()) - return 0; + if (!global_check_load()) { + return 0; + } - Provider *p; - { - p = global->manager->find(_p); - if(!p) - return 0; - } + Provider *p; + { + p = global->manager->find(_p); + if (!p) { + return 0; + } + } - return doCreateContext(p, type); + return doCreateContext(p, type); } //---------------------------------------------------------------------------- // Initializer //---------------------------------------------------------------------------- Initializer::Initializer(MemoryMode m, int prealloc) { - init(m, prealloc); + init(m, prealloc); } Initializer::~Initializer() { - deinit(); + deinit(); } //---------------------------------------------------------------------------- @@ -931,69 +967,69 @@ int Provider::version() const { - return 0; + return 0; } QString Provider::credit() const { - return QString(); + return QString(); } QVariantMap Provider::defaultConfig() const { - return QVariantMap(); + return QVariantMap(); } void Provider::configChanged(const QVariantMap &) { } Provider::Context::Context(Provider *parent, const QString &type) -:QObject() + : QObject() { - _provider = parent; - _type = type; + _provider = parent; + _type = type; } Provider::Context::Context(const Context &from) -:QObject() + : QObject() { - _provider = from._provider; - _type = from._type; + _provider = from._provider; + _type = from._type; } Provider::Context::~Context() { } Provider *Provider::Context::provider() const { - return _provider; + return _provider; } QString Provider::Context::type() const { - return _type; + return _type; } bool Provider::Context::sameProvider(const Context *c) const { - return (c->provider() == _provider); + return (c->provider() == _provider); } //---------------------------------------------------------------------------- // BasicContext //---------------------------------------------------------------------------- BasicContext::BasicContext(Provider *parent, const QString &type) -:Context(parent, type) + : Context(parent, type) { - moveToThread(0); // no thread association + moveToThread(0); // no thread association } BasicContext::BasicContext(const BasicContext &from) -:Context(from) + : Context(from) { - moveToThread(0); // no thread association + moveToThread(0); // no thread association } BasicContext::~BasicContext() @@ -1005,40 +1041,40 @@ //---------------------------------------------------------------------------- QStringList InfoContext::supportedHashTypes() const { - return QStringList(); + return QStringList(); } QStringList InfoContext::supportedCipherTypes() const { - return QStringList(); + return QStringList(); } QStringList InfoContext::supportedMACTypes() const { - return QStringList(); + return QStringList(); } //---------------------------------------------------------------------------- // PKeyBase //---------------------------------------------------------------------------- PKeyBase::PKeyBase(Provider *p, const QString &type) -:BasicContext(p, type) + : BasicContext(p, type) { } int PKeyBase::maximumEncryptSize(EncryptionAlgorithm) const { - return 0; + return 0; } SecureArray PKeyBase::encrypt(const SecureArray &, EncryptionAlgorithm) { - return SecureArray(); + return SecureArray(); } bool PKeyBase::decrypt(const SecureArray &, SecureArray *, EncryptionAlgorithm) { - return false; + return false; } void PKeyBase::startSign(SignatureAlgorithm, SignatureFormat) @@ -1055,162 +1091,160 @@ QByteArray PKeyBase::endSign() { - return QByteArray(); + return QByteArray(); } bool PKeyBase::endVerify(const QByteArray &) { - return false; + return false; } SymmetricKey PKeyBase::deriveKey(const PKeyBase &) { - return SymmetricKey(); + return SymmetricKey(); } //---------------------------------------------------------------------------- // PKeyContext //---------------------------------------------------------------------------- QByteArray PKeyContext::publicToDER() const { - return QByteArray(); + return QByteArray(); } QString PKeyContext::publicToPEM() const { - return QString(); + return QString(); } ConvertResult PKeyContext::publicFromDER(const QByteArray &) { - return ErrorDecode; + return ErrorDecode; } ConvertResult PKeyContext::publicFromPEM(const QString &) { - return ErrorDecode; + return ErrorDecode; } SecureArray PKeyContext::privateToDER(const SecureArray &, PBEAlgorithm) const { - return SecureArray(); + return SecureArray(); } QString PKeyContext::privateToPEM(const SecureArray &, PBEAlgorithm) const { - return QString(); + return QString(); } ConvertResult PKeyContext::privateFromDER(const SecureArray &, const SecureArray &) { - return ErrorDecode; + return ErrorDecode; } ConvertResult PKeyContext::privateFromPEM(const QString &, const SecureArray &) { - return ErrorDecode; + return ErrorDecode; } //---------------------------------------------------------------------------- // KeyStoreEntryContext //---------------------------------------------------------------------------- bool KeyStoreEntryContext::isAvailable() const { - return true; + return true; } KeyBundle KeyStoreEntryContext::keyBundle() const { - return KeyBundle(); + return KeyBundle(); } Certificate KeyStoreEntryContext::certificate() const { - return Certificate(); + return Certificate(); } CRL KeyStoreEntryContext::crl() const { - return CRL(); + return CRL(); } PGPKey KeyStoreEntryContext::pgpSecretKey() const { - return PGPKey(); + return PGPKey(); } PGPKey KeyStoreEntryContext::pgpPublicKey() const { - return PGPKey(); + return PGPKey(); } bool KeyStoreEntryContext::ensureAccess() { - return true; + return true; } //---------------------------------------------------------------------------- // KeyStoreListContext //---------------------------------------------------------------------------- void KeyStoreListContext::start() { - QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection); } void KeyStoreListContext::setUpdatesEnabled(bool) { } bool KeyStoreListContext::isReadOnly(int) const { - return true; + return true; } KeyStoreEntryContext *KeyStoreListContext::entry(int id, const QString &entryId) { - KeyStoreEntryContext *out = 0; - QList list = entryList(id); - for(int n = 0; n < list.count(); ++n) - { - if(list[n]->id() == entryId) - { - out = list.takeAt(n); - break; - } - } - qDeleteAll(list); - return out; + KeyStoreEntryContext *out = 0; + QList list = entryList(id); + for (int n = 0; n < list.count(); ++n) { + if (list[n]->id() == entryId) { + out = list.takeAt(n); + break; + } + } + qDeleteAll(list); + return out; } KeyStoreEntryContext *KeyStoreListContext::entryPassive(const QString &serialized) { - Q_UNUSED(serialized); - return 0; + Q_UNUSED(serialized); + return 0; } QString KeyStoreListContext::writeEntry(int, const KeyBundle &) { - return QString(); + return QString(); } QString KeyStoreListContext::writeEntry(int, const Certificate &) { - return QString(); + return QString(); } QString KeyStoreListContext::writeEntry(int, const CRL &) { - return QString(); + return QString(); } QString KeyStoreListContext::writeEntry(int, const PGPKey &) { - return QString(); + return QString(); } bool KeyStoreListContext::removeEntry(int, const QString &) { - return false; + return false; } //---------------------------------------------------------------------------- @@ -1225,7 +1259,7 @@ //---------------------------------------------------------------------------- QString MessageContext::diagnosticText() const { - return QString(); + return QString(); } //---------------------------------------------------------------------------- @@ -1252,9 +1286,9 @@ MemoryRegion BufferedComputation::process(const MemoryRegion &a) { - clear(); - update(a); - return final(); + clear(); + update(a); + return final(); } //---------------------------------------------------------------------------- @@ -1266,129 +1300,137 @@ MemoryRegion Filter::process(const MemoryRegion &a) { - clear(); - MemoryRegion buf = update(a); - if(!ok()) - return MemoryRegion(); - MemoryRegion fin = final(); - if(!ok()) - return MemoryRegion(); - if(buf.isSecure() || fin.isSecure()) - return (SecureArray(buf) + SecureArray(fin)); - else - return (buf.toByteArray() + fin.toByteArray()); + clear(); + MemoryRegion buf = update(a); + if (!ok()) { + return MemoryRegion(); + } + MemoryRegion fin = final(); + if (!ok()) { + return MemoryRegion(); + } + if (buf.isSecure() || fin.isSecure()) { + return (SecureArray(buf) + SecureArray(fin)); + } else { + return (buf.toByteArray() + fin.toByteArray()); + } } //---------------------------------------------------------------------------- // Algorithm //---------------------------------------------------------------------------- class Algorithm::Private : public QSharedData { public: - Provider::Context *c; - - Private(Provider::Context *context) - { - c = context; - //printf("** [%p] Algorithm Created\n", c); - } - - Private(const Private &from) : QSharedData(from) - { - c = from.c->clone(); - //printf("** [%p] Algorithm Copied (to [%p])\n", from.c, c); - } - - ~Private() - { - //printf("** [%p] Algorithm Destroyed\n", c); - delete c; - } + Provider::Context *c; + + Private(Provider::Context *context) + { + c = context; + //printf("** [%p] Algorithm Created\n", c); + } + + Private(const Private &from) : QSharedData(from) + { + c = from.c->clone(); + //printf("** [%p] Algorithm Copied (to [%p])\n", from.c, c); + } + + ~Private() + { + //printf("** [%p] Algorithm Destroyed\n", c); + delete c; + } }; Algorithm::Algorithm() { } Algorithm::Algorithm(const QString &type, const QString &provider) { - change(type, provider); + change(type, provider); } Algorithm::Algorithm(const Algorithm &from) { - *this = from; + *this = from; } Algorithm::~Algorithm() { } -Algorithm & Algorithm::operator=(const Algorithm &from) +Algorithm &Algorithm::operator=(const Algorithm &from) { - d = from.d; - return *this; + d = from.d; + return *this; } QString Algorithm::type() const { - if(d) - return d->c->type(); - else - return QString(); + if (d) { + return d->c->type(); + } else { + return QString(); + } } Provider *Algorithm::provider() const { - if(d) - return d->c->provider(); - else - return 0; + if (d) { + return d->c->provider(); + } else { + return 0; + } } Provider::Context *Algorithm::context() { - if(d) - return d->c; - else - return 0; + if (d) { + return d->c; + } else { + return 0; + } } const Provider::Context *Algorithm::context() const { - if(d) - return d->c; - else - return 0; + if (d) { + return d->c; + } else { + return 0; + } } void Algorithm::change(Provider::Context *c) { - if(c) - d = new Private(c); - else - d = 0; + if (c) { + d = new Private(c); + } else { + d = 0; + } } void Algorithm::change(const QString &type, const QString &provider) { - if(!type.isEmpty()) - change(getContext(type, provider)); - else - change(0); + if (!type.isEmpty()) { + change(getContext(type, provider)); + } else { + change(0); + } } Provider::Context *Algorithm::takeContext() { - if(d) - { - Provider::Context *c = d->c; // should cause a detach - d->c = 0; - d = 0; - return c; - } - else - return 0; + if (d) { + Provider::Context *c = d->c; // should cause a detach + d->c = 0; + d = 0; + return c; + } else { + return 0; + } } //---------------------------------------------------------------------------- @@ -1400,103 +1442,104 @@ SymmetricKey::SymmetricKey(int size) { - set(Random::randomArray(size)); + set(Random::randomArray(size)); } SymmetricKey::SymmetricKey(const SecureArray &a) { - set(a); + set(a); } SymmetricKey::SymmetricKey(const QByteArray &a) { - set(SecureArray(a)); + set(SecureArray(a)); } /* from libgcrypt-1.2.0 */ -static unsigned char desWeakKeyTable[64][8] = -{ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/ - { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e }, - { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 }, - { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe }, - { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/ - { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 }, - { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe }, - { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 }, - { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/ - { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe }, - { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 }, - { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e }, - { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/ - { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 }, - { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e }, - { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 }, - { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e }, - { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/ - { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe }, - { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 }, - { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 }, - { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/ - { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 }, - { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe }, - { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe }, - { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/ - { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e }, - { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 }, - { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 }, - { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/ - { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 }, - { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e }, - { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 }, - { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe }, - { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/ - { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e }, - { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe }, - { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 }, - { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/ - { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 }, - { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 }, - { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e }, - { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/ - { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe }, - { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e }, - { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 }, - { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/ - { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 }, - { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe }, - { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 }, - { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e }, - { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/ - { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 }, - { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe }, - { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 }, - { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/ - { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e }, - { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 }, - { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe }, - { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/ - { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 }, - { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e }, - { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 }, - { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe } /*w*/ +static unsigned char desWeakKeyTable[64][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/ + { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e }, + { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 }, + { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe }, + { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/ + { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 }, + { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe }, + { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 }, + { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/ + { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe }, + { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 }, + { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e }, + { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/ + { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 }, + { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e }, + { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 }, + { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e }, + { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/ + { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe }, + { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 }, + { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 }, + { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/ + { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 }, + { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe }, + { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe }, + { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/ + { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e }, + { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 }, + { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 }, + { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/ + { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 }, + { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e }, + { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 }, + { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe }, + { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/ + { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e }, + { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe }, + { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 }, + { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/ + { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 }, + { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 }, + { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e }, + { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/ + { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe }, + { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e }, + { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 }, + { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/ + { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 }, + { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe }, + { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 }, + { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e }, + { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/ + { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 }, + { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe }, + { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 }, + { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/ + { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e }, + { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 }, + { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe }, + { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/ + { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 }, + { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e }, + { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 }, + { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe } /*w*/ }; bool SymmetricKey::isWeakDESKey() { - if(size() != 8) - return false; // dubious - SecureArray workingCopy(8); - // clear parity bits - for(uint i = 0; i < 8; i++) - workingCopy[i] = (data()[i]) & 0xfe; + if (size() != 8) { + return false; // dubious + } + SecureArray workingCopy(8); + // clear parity bits + for (uint i = 0; i < 8; i++) { + workingCopy[i] = (data()[i]) & 0xfe; + } - for(int n = 0; n < 64; n++) - { - if(memcmp(workingCopy.data(), desWeakKeyTable[n], 8) == 0) - return true; - } - return false; + for (int n = 0; n < 64; n++) { + if (memcmp(workingCopy.data(), desWeakKeyTable[n], 8) == 0) { + return true; + } + } + return false; } //---------------------------------------------------------------------------- @@ -1508,17 +1551,17 @@ InitializationVector::InitializationVector(int size) { - set(Random::randomArray(size)); + set(Random::randomArray(size)); } InitializationVector::InitializationVector(const SecureArray &a) { - set(a); + set(a); } InitializationVector::InitializationVector(const QByteArray &a) { - set(SecureArray(a)); + set(SecureArray(a)); } //---------------------------------------------------------------------------- @@ -1530,157 +1573,160 @@ AuthTag::AuthTag(int size) { - resize(size); + resize(size); } AuthTag::AuthTag(const SecureArray &a) { - set(a); + set(a); } AuthTag::AuthTag(const QByteArray &a) { - set(SecureArray(a)); + set(SecureArray(a)); } //---------------------------------------------------------------------------- // Event //---------------------------------------------------------------------------- class Event::Private : public QSharedData { public: - Type type; - Source source; - PasswordStyle style; - KeyStoreInfo ksi; - KeyStoreEntry kse; - QString fname; - void *ptr; + Type type; + Source source; + PasswordStyle style; + KeyStoreInfo ksi; + KeyStoreEntry kse; + QString fname; + void *ptr; }; Event::Event() { } Event::Event(const Event &from) -:d(from.d) + : d(from.d) { } Event::~Event() { } -Event & Event::operator=(const Event &from) +Event &Event::operator=(const Event &from) { - d = from.d; - return *this; + d = from.d; + return *this; } bool Event::isNull() const { - return (d ? false : true); + return (d ? false : true); } Event::Type Event::type() const { - return d->type; + return d->type; } Event::Source Event::source() const { - return d->source; + return d->source; } Event::PasswordStyle Event::passwordStyle() const { - return d->style; + return d->style; } KeyStoreInfo Event::keyStoreInfo() const { - return d->ksi; + return d->ksi; } KeyStoreEntry Event::keyStoreEntry() const { - return d->kse; + return d->kse; } QString Event::fileName() const { - return d->fname; + return d->fname; } void *Event::ptr() const { - return d->ptr; + return d->ptr; } void Event::setPasswordKeyStore(PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr) { - if(!d) - d = new Private; - d->type = Password; - d->source = KeyStore; - d->style = pstyle; - d->ksi = keyStoreInfo; - d->kse = keyStoreEntry; - d->fname = QString(); - d->ptr = ptr; + if (!d) { + d = new Private; + } + d->type = Password; + d->source = KeyStore; + d->style = pstyle; + d->ksi = keyStoreInfo; + d->kse = keyStoreEntry; + d->fname = QString(); + d->ptr = ptr; } void Event::setPasswordData(PasswordStyle pstyle, const QString &fileName, void *ptr) { - if(!d) - d = new Private; - d->type = Password; - d->source = Data; - d->style = pstyle; - d->ksi = KeyStoreInfo(); - d->kse = KeyStoreEntry(); - d->fname = fileName; - d->ptr = ptr; + if (!d) { + d = new Private; + } + d->type = Password; + d->source = Data; + d->style = pstyle; + d->ksi = KeyStoreInfo(); + d->kse = KeyStoreEntry(); + d->fname = fileName; + d->ptr = ptr; } void Event::setToken(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr) { - if(!d) - d = new Private; - d->type = Token; - d->source = KeyStore; - d->style = StylePassword; - d->ksi = keyStoreInfo; - d->kse = keyStoreEntry; - d->fname = QString(); - d->ptr = ptr; + if (!d) { + d = new Private; + } + d->type = Token; + d->source = KeyStore; + d->style = StylePassword; + d->ksi = keyStoreInfo; + d->kse = keyStoreEntry; + d->fname = QString(); + d->ptr = ptr; } //---------------------------------------------------------------------------- // EventGlobal //---------------------------------------------------------------------------- class HandlerBase : public QObject { - Q_OBJECT + Q_OBJECT public: - HandlerBase(QObject *parent = 0) : QObject(parent) - { - } + HandlerBase(QObject *parent = 0) : QObject(parent) + { + } protected slots: - virtual void ask(int id, const QCA::Event &e) = 0; + virtual void ask(int id, const QCA::Event &e) = 0; }; class AskerBase : public QObject { - Q_OBJECT + Q_OBJECT public: - AskerBase(QObject *parent = 0) : QObject(parent) - { - } + AskerBase(QObject *parent = 0) : QObject(parent) + { + } - virtual void set_accepted(const SecureArray &password) = 0; - virtual void set_rejected() = 0; + virtual void set_accepted(const SecureArray &password) = 0; + virtual void set_rejected() = 0; }; static void handler_add(HandlerBase *h, int pos = -1); @@ -1698,535 +1744,548 @@ class EventGlobal { public: - class HandlerItem - { - public: - HandlerBase *h; - QList ids; - }; - - class AskerItem - { - public: - AskerBase *a; - int id; - Event event; - int handler_pos; - }; - - QList handlers; - QList askers; - - int next_id; - - EventGlobal() - { - qRegisterMetaType("QCA::Event"); - qRegisterMetaType("QCA::SecureArray"); - next_id = 0; - } - - int findHandlerItem(HandlerBase *h) - { - for(int n = 0; n < handlers.count(); ++n) - { - if(handlers[n].h == h) - return n; - } - return -1; - } - - int findAskerItem(AskerBase *a) - { - for(int n = 0; n < askers.count(); ++n) - { - if(askers[n].a == a) - return n; - } - return -1; - } - - int findAskerItemById(int id) - { - for(int n = 0; n < askers.count(); ++n) - { - if(askers[n].id == id) - return n; - } - return -1; - } - - void ask(int asker_at) - { - AskerItem &i = askers[asker_at]; - - g_event->handlers[i.handler_pos].ids += i.id; - QMetaObject::invokeMethod(handlers[i.handler_pos].h, "ask", - Qt::QueuedConnection, Q_ARG(int, i.id), - Q_ARG(QCA::Event, i.event)); - } - - void reject(int asker_at) - { - AskerItem &i = askers[asker_at]; - - // look for the next usable handler - int pos = -1; - for(int n = i.handler_pos + 1; n < g_event->handlers.count(); ++n) - { - // handler and asker can't be in the same thread - //Q_ASSERT(g_event->handlers[n].h->thread() != i.a->thread()); - //if(g_event->handlers[n].h->thread() != i.a->thread()) - //{ - pos = n; - break; - //} - } - - // if there is one, try it - if(pos != -1) - { - i.handler_pos = pos; - ask(asker_at); - } - // if not, send official reject - else - { - AskerBase *asker = i.a; - askers.removeAt(asker_at); - - asker->set_rejected(); - } - } + class HandlerItem + { + public: + HandlerBase *h; + QList ids; + }; + + class AskerItem + { + public: + AskerBase *a; + int id; + Event event; + int handler_pos; + }; + + QList handlers; + QList askers; + + int next_id; + + EventGlobal() + { + qRegisterMetaType("QCA::Event"); + qRegisterMetaType("QCA::SecureArray"); + next_id = 0; + } + + int findHandlerItem(HandlerBase *h) + { + for (int n = 0; n < handlers.count(); ++n) { + if (handlers[n].h == h) { + return n; + } + } + return -1; + } + + int findAskerItem(AskerBase *a) + { + for (int n = 0; n < askers.count(); ++n) { + if (askers[n].a == a) { + return n; + } + } + return -1; + } + + int findAskerItemById(int id) + { + for (int n = 0; n < askers.count(); ++n) { + if (askers[n].id == id) { + return n; + } + } + return -1; + } + + void ask(int asker_at) + { + AskerItem &i = askers[asker_at]; + + g_event->handlers[i.handler_pos].ids += i.id; + QMetaObject::invokeMethod(handlers[i.handler_pos].h, "ask", + Qt::QueuedConnection, Q_ARG(int, i.id), + Q_ARG(QCA::Event, i.event)); + } + + void reject(int asker_at) + { + AskerItem &i = askers[asker_at]; + + // look for the next usable handler + int pos = -1; + for (int n = i.handler_pos + 1; n < g_event->handlers.count(); ++n) { + // handler and asker can't be in the same thread + //Q_ASSERT(g_event->handlers[n].h->thread() != i.a->thread()); + //if(g_event->handlers[n].h->thread() != i.a->thread()) + //{ + pos = n; + break; + //} + } + + // if there is one, try it + if (pos != -1) { + i.handler_pos = pos; + ask(asker_at); + } + // if not, send official reject + else { + AskerBase *asker = i.a; + askers.removeAt(asker_at); + + asker->set_rejected(); + } + } }; void handler_add(HandlerBase *h, int pos) { - QMutexLocker locker(g_event_mutex()); - if(!g_event) - g_event = new EventGlobal; + QMutexLocker locker(g_event_mutex()); + if (!g_event) { + g_event = new EventGlobal; + } - EventGlobal::HandlerItem i; - i.h = h; + EventGlobal::HandlerItem i; + i.h = h; - if(pos != -1) - { - g_event->handlers.insert(pos, i); + if (pos != -1) { + g_event->handlers.insert(pos, i); - // adjust handler positions - for(int n = 0; n < g_event->askers.count(); ++n) - { - if(g_event->askers[n].handler_pos >= pos) - g_event->askers[n].handler_pos++; - } - } - else - g_event->handlers += i; + // adjust handler positions + for (int n = 0; n < g_event->askers.count(); ++n) { + if (g_event->askers[n].handler_pos >= pos) { + g_event->askers[n].handler_pos++; + } + } + } else { + g_event->handlers += i; + } } void handler_remove(HandlerBase *h) { - QMutexLocker locker(g_event_mutex()); - Q_ASSERT(g_event); - if(!g_event) - return; - int at = g_event->findHandlerItem(h); - Q_ASSERT(at != -1); - if(at == -1) - return; - - QList ids = g_event->handlers[at].ids; - g_event->handlers.removeAt(at); - - // adjust handler positions within askers - for(int n = 0; n < g_event->askers.count(); ++n) - { - if(g_event->askers[n].handler_pos >= at) - g_event->askers[n].handler_pos--; - } - - // reject all askers - foreach(int id, ids) - { - int asker_at = g_event->findAskerItemById(id); - Q_ASSERT(asker_at != -1); - - g_event->reject(asker_at); - } - - if(g_event->handlers.isEmpty()) - { - delete g_event; - g_event = 0; - } + QMutexLocker locker(g_event_mutex()); + Q_ASSERT(g_event); + if (!g_event) { + return; + } + int at = g_event->findHandlerItem(h); + Q_ASSERT(at != -1); + if (at == -1) { + return; + } + + QList ids = g_event->handlers[at].ids; + g_event->handlers.removeAt(at); + + // adjust handler positions within askers + for (int n = 0; n < g_event->askers.count(); ++n) { + if (g_event->askers[n].handler_pos >= at) { + g_event->askers[n].handler_pos--; + } + } + + // reject all askers + foreach (int id, ids) { + int asker_at = g_event->findAskerItemById(id); + Q_ASSERT(asker_at != -1); + + g_event->reject(asker_at); + } + + if (g_event->handlers.isEmpty()) { + delete g_event; + g_event = 0; + } } void handler_accept(HandlerBase *h, int id, const SecureArray &password) { - QMutexLocker locker(g_event_mutex()); - Q_ASSERT(g_event); - if(!g_event) - return; - int at = g_event->findHandlerItem(h); - Q_ASSERT(at != -1); - if(at == -1) - return; - int asker_at = g_event->findAskerItemById(id); - Q_ASSERT(asker_at != -1); - if(asker_at == -1) - return; + QMutexLocker locker(g_event_mutex()); + Q_ASSERT(g_event); + if (!g_event) { + return; + } + int at = g_event->findHandlerItem(h); + Q_ASSERT(at != -1); + if (at == -1) { + return; + } + int asker_at = g_event->findAskerItemById(id); + Q_ASSERT(asker_at != -1); + if (asker_at == -1) { + return; + } - g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id); + g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id); - AskerBase *asker = g_event->askers[asker_at].a; - asker->set_accepted(password); + AskerBase *asker = g_event->askers[asker_at].a; + asker->set_accepted(password); } void handler_reject(HandlerBase *h, int id) { - QMutexLocker locker(g_event_mutex()); - Q_ASSERT(g_event); - if(!g_event) - return; - int at = g_event->findHandlerItem(h); - Q_ASSERT(at != -1); - if(at == -1) - return; - int asker_at = g_event->findAskerItemById(id); - Q_ASSERT(asker_at != -1); - if(asker_at == -1) - return; + QMutexLocker locker(g_event_mutex()); + Q_ASSERT(g_event); + if (!g_event) { + return; + } + int at = g_event->findHandlerItem(h); + Q_ASSERT(at != -1); + if (at == -1) { + return; + } + int asker_at = g_event->findAskerItemById(id); + Q_ASSERT(asker_at != -1); + if (asker_at == -1) { + return; + } - g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id); + g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id); - g_event->reject(asker_at); + g_event->reject(asker_at); } bool asker_ask(AskerBase *a, const Event &e) { - QMutexLocker locker(g_event_mutex()); - if(!g_event) - return false; - - int pos = -1; - for(int n = 0; n < g_event->handlers.count(); ++n) - { - // handler and asker can't be in the same thread - //Q_ASSERT(g_event->handlers[n].h->thread() != a->thread()); - //if(g_event->handlers[n].h->thread() != a->thread()) - //{ - pos = n; - break; - //} - } - if(pos == -1) - return false; - - EventGlobal::AskerItem i; - i.a = a; - i.id = g_event->next_id++; - i.event = e; - i.handler_pos = pos; - g_event->askers += i; - int asker_at = g_event->askers.count() - 1; - - g_event->ask(asker_at); - return true; + QMutexLocker locker(g_event_mutex()); + if (!g_event) { + return false; + } + + int pos = -1; + for (int n = 0; n < g_event->handlers.count(); ++n) { + // handler and asker can't be in the same thread + //Q_ASSERT(g_event->handlers[n].h->thread() != a->thread()); + //if(g_event->handlers[n].h->thread() != a->thread()) + //{ + pos = n; + break; + //} + } + if (pos == -1) { + return false; + } + + EventGlobal::AskerItem i; + i.a = a; + i.id = g_event->next_id++; + i.event = e; + i.handler_pos = pos; + g_event->askers += i; + int asker_at = g_event->askers.count() - 1; + + g_event->ask(asker_at); + return true; } void asker_cancel(AskerBase *a) { - QMutexLocker locker(g_event_mutex()); - if(!g_event) - return; - int at = g_event->findAskerItem(a); - if(at == -1) - return; + QMutexLocker locker(g_event_mutex()); + if (!g_event) { + return; + } + int at = g_event->findAskerItem(a); + if (at == -1) { + return; + } - for(int n = 0; n < g_event->handlers.count(); ++n) - g_event->handlers[n].ids.removeAll(g_event->askers[at].id); + for (int n = 0; n < g_event->handlers.count(); ++n) { + g_event->handlers[n].ids.removeAll(g_event->askers[at].id); + } - g_event->askers.removeAt(at); + g_event->askers.removeAt(at); } //---------------------------------------------------------------------------- // EventHandler //---------------------------------------------------------------------------- class EventHandler::Private : public HandlerBase { - Q_OBJECT + Q_OBJECT public: - EventHandler *q; - bool started; - QList activeIds; + EventHandler *q; + bool started; + QList activeIds; - Private(EventHandler *_q) : HandlerBase(_q), q(_q) - { - started = false; - } + Private(EventHandler *_q) : HandlerBase(_q), q(_q) + { + started = false; + } public slots: - virtual void ask(int id, const QCA::Event &e) - { - activeIds += id; - emit q->eventReady(id, e); - } + virtual void ask(int id, const QCA::Event &e) + { + activeIds += id; + emit q->eventReady(id, e); + } }; EventHandler::EventHandler(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); + d = new Private(this); } EventHandler::~EventHandler() { - if(d->started) - { - foreach(int id, d->activeIds) - handler_reject(d, id); + if (d->started) { + foreach (int id, d->activeIds) { + handler_reject(d, id); + } - handler_remove(d); - } + handler_remove(d); + } - delete d; + delete d; } void EventHandler::start() { - d->started = true; - handler_add(d); + d->started = true; + handler_add(d); } void EventHandler::submitPassword(int id, const SecureArray &password) { - if(!d->activeIds.contains(id)) - return; + if (!d->activeIds.contains(id)) { + return; + } - d->activeIds.removeAll(id); - handler_accept(d, id, password); + d->activeIds.removeAll(id); + handler_accept(d, id, password); } void EventHandler::tokenOkay(int id) { - if(!d->activeIds.contains(id)) - return; + if (!d->activeIds.contains(id)) { + return; + } - d->activeIds.removeAll(id); - handler_accept(d, id, SecureArray()); + d->activeIds.removeAll(id); + handler_accept(d, id, SecureArray()); } void EventHandler::reject(int id) { - if(!d->activeIds.contains(id)) - return; + if (!d->activeIds.contains(id)) { + return; + } - d->activeIds.removeAll(id); - handler_reject(d, id); + d->activeIds.removeAll(id); + handler_reject(d, id); } //---------------------------------------------------------------------------- // PasswordAsker //---------------------------------------------------------------------------- class AskerPrivate : public AskerBase { - Q_OBJECT + Q_OBJECT public: - enum Type { Password, Token }; - - Type type; - PasswordAsker *passwordAsker; - TokenAsker *tokenAsker; - - QMutex m; - QWaitCondition w; - - bool accepted; - SecureArray password; - bool waiting; - bool done; - - AskerPrivate(PasswordAsker *parent) : AskerBase(parent) - { - passwordAsker = parent; - tokenAsker = 0; - type = Password; - accepted = false; - waiting = false; - done = true; - } - - AskerPrivate(TokenAsker *parent) : AskerBase(parent) - { - passwordAsker = 0; - tokenAsker = parent; - type = Token; - accepted = false; - waiting = false; - done = true; - } - - void ask(const Event &e) - { - accepted = false; - waiting = false; - done = false; - password.clear(); - - if(!asker_ask(this, e)) - { - done = true; - QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection); - } - } - - void cancel() - { - if(!done) - asker_cancel(this); - } - - virtual void set_accepted(const SecureArray &_password) - { - QMutexLocker locker(&m); - accepted = true; - password = _password; - done = true; - if(waiting) - w.wakeOne(); - else - QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection); - } - - virtual void set_rejected() - { - QMutexLocker locker(&m); - done = true; - if(waiting) - w.wakeOne(); - else - QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection); - } - - void waitForResponse() - { - QMutexLocker locker(&m); - if(done) - return; - waiting = true; - w.wait(&m); - waiting = false; - } + enum Type { Password, Token }; + + Type type; + PasswordAsker *passwordAsker; + TokenAsker *tokenAsker; + + QMutex m; + QWaitCondition w; + + bool accepted; + SecureArray password; + bool waiting; + bool done; + + AskerPrivate(PasswordAsker *parent) : AskerBase(parent) + { + passwordAsker = parent; + tokenAsker = 0; + type = Password; + accepted = false; + waiting = false; + done = true; + } + + AskerPrivate(TokenAsker *parent) : AskerBase(parent) + { + passwordAsker = 0; + tokenAsker = parent; + type = Token; + accepted = false; + waiting = false; + done = true; + } + + void ask(const Event &e) + { + accepted = false; + waiting = false; + done = false; + password.clear(); + + if (!asker_ask(this, e)) { + done = true; + QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection); + } + } + + void cancel() + { + if (!done) { + asker_cancel(this); + } + } + + virtual void set_accepted(const SecureArray &_password) + { + QMutexLocker locker(&m); + accepted = true; + password = _password; + done = true; + if (waiting) { + w.wakeOne(); + } else { + QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection); + } + } + + virtual void set_rejected() + { + QMutexLocker locker(&m); + done = true; + if (waiting) { + w.wakeOne(); + } else { + QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection); + } + } + + void waitForResponse() + { + QMutexLocker locker(&m); + if (done) { + return; + } + waiting = true; + w.wait(&m); + waiting = false; + } public slots: - virtual void emitResponseReady() = 0; + virtual void emitResponseReady() = 0; }; class PasswordAsker::Private : public AskerPrivate { public: - Private(PasswordAsker *_q) : AskerPrivate(_q) - { - } - - virtual void emitResponseReady() - { - emit passwordAsker->responseReady(); - } + Private(PasswordAsker *_q) : AskerPrivate(_q) + { + } + + virtual void emitResponseReady() + { + emit passwordAsker->responseReady(); + } }; PasswordAsker::PasswordAsker(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); + d = new Private(this); } PasswordAsker::~PasswordAsker() { - delete d; + delete d; } void PasswordAsker::ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr) { - Event e; - e.setPasswordKeyStore(pstyle, keyStoreInfo, keyStoreEntry, ptr); - d->ask(e); + Event e; + e.setPasswordKeyStore(pstyle, keyStoreInfo, keyStoreEntry, ptr); + d->ask(e); } void PasswordAsker::ask(Event::PasswordStyle pstyle, const QString &fileName, void *ptr) { - Event e; - e.setPasswordData(pstyle, fileName, ptr); - d->ask(e); + Event e; + e.setPasswordData(pstyle, fileName, ptr); + d->ask(e); } void PasswordAsker::cancel() { - d->cancel(); + d->cancel(); } void PasswordAsker::waitForResponse() { - d->waitForResponse(); + d->waitForResponse(); } bool PasswordAsker::accepted() const { - return d->accepted; + return d->accepted; } SecureArray PasswordAsker::password() const { - return d->password; + return d->password; } //---------------------------------------------------------------------------- // TokenAsker //---------------------------------------------------------------------------- class TokenAsker::Private : public AskerPrivate { public: - Private(TokenAsker *_q) : AskerPrivate(_q) - { - } - - virtual void emitResponseReady() - { - emit tokenAsker->responseReady(); - } + Private(TokenAsker *_q) : AskerPrivate(_q) + { + } + + virtual void emitResponseReady() + { + emit tokenAsker->responseReady(); + } }; TokenAsker::TokenAsker(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); + d = new Private(this); } TokenAsker::~TokenAsker() { - delete d; + delete d; } void TokenAsker::ask(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr) { - Event e; - e.setToken(keyStoreInfo, keyStoreEntry, ptr); - d->ask(e); + Event e; + e.setToken(keyStoreInfo, keyStoreEntry, ptr); + d->ask(e); } void TokenAsker::cancel() { - d->cancel(); + d->cancel(); } void TokenAsker::waitForResponse() { - d->waitForResponse(); + d->waitForResponse(); } bool TokenAsker::accepted() const { - return d->accepted; + return d->accepted; } } diff --git a/src/qca_default.cpp b/src/qca_default.cpp --- a/src/qca_default.cpp +++ b/src/qca_default.cpp @@ -32,76 +32,78 @@ #define FRIENDLY_NAMES -namespace QCA { +namespace QCA +{ class DefaultShared { private: - mutable QMutex m; - bool _use_system; - QString _roots_file; - QStringList _skip_plugins; - QStringList _plugin_priorities; + mutable QMutex m; + bool _use_system; + QString _roots_file; + QStringList _skip_plugins; + QStringList _plugin_priorities; public: - DefaultShared() : _use_system(true) - { - } - - bool use_system() const - { - QMutexLocker locker(&m); - return _use_system; - } - - QString roots_file() const - { - QMutexLocker locker(&m); - return _roots_file; - } - - QStringList skip_plugins() const - { - QMutexLocker locker(&m); - return _skip_plugins; - } - - QStringList plugin_priorities() const - { - QMutexLocker locker(&m); - return _plugin_priorities; - } - - void set(bool use_system, const QString &roots_file, const QStringList &skip_plugins, const QStringList &plugin_priorities) - { - QMutexLocker locker(&m); - _use_system = use_system; - _roots_file = roots_file; - _skip_plugins = skip_plugins; - _plugin_priorities = plugin_priorities; - } + DefaultShared() : _use_system(true) + { + } + + bool use_system() const + { + QMutexLocker locker(&m); + return _use_system; + } + + QString roots_file() const + { + QMutexLocker locker(&m); + return _roots_file; + } + + QStringList skip_plugins() const + { + QMutexLocker locker(&m); + return _skip_plugins; + } + + QStringList plugin_priorities() const + { + QMutexLocker locker(&m); + return _plugin_priorities; + } + + void set(bool use_system, const QString &roots_file, const QStringList &skip_plugins, const QStringList &plugin_priorities) + { + QMutexLocker locker(&m); + _use_system = use_system; + _roots_file = roots_file; + _skip_plugins = skip_plugins; + _plugin_priorities = plugin_priorities; + } }; //---------------------------------------------------------------------------- // DefaultRandomContext //---------------------------------------------------------------------------- class DefaultRandomContext : public RandomContext { public: - DefaultRandomContext(Provider *p) : RandomContext(p) {} - - virtual Provider::Context *clone() const - { - return new DefaultRandomContext(provider()); - } - - virtual SecureArray nextBytes(int size) - { - SecureArray buf(size); - for(int n = 0; n < (int)buf.size(); ++n) - buf[n] = (char)qrand(); - return buf; - } + DefaultRandomContext(Provider *p) : RandomContext(p) {} + + virtual Provider::Context *clone() const + { + return new DefaultRandomContext(provider()); + } + + virtual SecureArray nextBytes(int size) + { + SecureArray buf(size); + for (int n = 0; n < (int)buf.size(); ++n) { + buf[n] = (char)qrand(); + } + return buf; + } }; //---------------------------------------------------------------------------- @@ -139,7 +141,7 @@ This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at - http://www.ietf.org/rfc/rfc1321.txt + http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being @@ -150,14 +152,14 @@ that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. + either statically or dynamically; added missing #include + in library. 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. + type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. + unsigned in ANSI C, signed in traditional"; made test program + self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. @@ -194,7 +196,7 @@ *this = from; } - md5_state_t & operator=(const md5_state_t &from) + md5_state_t &operator=(const md5_state_t &from) { *this = from; return *this; @@ -276,63 +278,60 @@ #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) { - md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - md5_word_t t; - - /* Define storage for little-endian or both types of CPUs. */ - md5_word_t xbuf[16]; - const md5_word_t *X; - - { - if(QSysInfo::ByteOrder == QSysInfo::BigEndian) - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const md5_byte_t *xp = data; - int i; - - X = xbuf; /* (dynamic only) */ - - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } - else /* dynamic big-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. On arm do copying always - */ + md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; + + /* Define storage for little-endian or both types of CPUs. */ + md5_word_t xbuf[16]; + const md5_word_t *X; + + { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const md5_byte_t *xp = data; + int i; + + X = xbuf; /* (dynamic only) */ + + for (i = 0; i < 16; ++i, xp += 4) { + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } + } else { /* dynamic big-endian */ + /* + * On little-endian machines, we can process properly aligned + * data without copying it. On arm do copying always + */ #ifndef Q_PROCESSOR_ARM - if (!((data - static_cast(0)) & 3)) { - /* data are properly aligned */ - X = reinterpret_cast(data); - } else + if (!((data - static_cast(0)) & 3)) { + /* data are properly aligned */ + X = reinterpret_cast(data); + } else #endif - { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } - } + { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } + } #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); @@ -352,14 +351,14 @@ SET(b, c, d, a, 15, 22, T16); #undef SET - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); @@ -378,14 +377,14 @@ SET(b, c, d, a, 12, 20, T32); #undef SET - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); @@ -404,14 +403,14 @@ SET(b, c, d, a, 2, 23, T48); #undef SET - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); @@ -430,9 +429,9 @@ SET(b, c, d, a, 9, 21, T64); #undef SET - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ pms->abcd[0] += a; pms->abcd[1] += b; pms->abcd[2] += c; @@ -457,103 +456,108 @@ int offset = (pms->count[0] >> 3) & 63; md5_word_t nbits = (md5_word_t)(nbytes << 3); - if (nbytes <= 0) - return; + if (nbytes <= 0) { + return; + } /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; + if (pms->count[0] < nbits) { + pms->count[1]++; + } /* Process an initial partial block. */ if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) { + return; + } + p += copy; + left -= copy; + md5_process(pms, pms->buf); } /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); + for (; left >= 64; p += 64, left -= 64) { + md5_process(pms, p); + } /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); + if (left) { + memcpy(pms->buf, p, left); + } } void md5_finish(md5_state_t *pms, md5_byte_t digest[16]) { static const md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; md5_byte_t data[8]; int i; /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + for (i = 0; i < 8; ++i) { + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + } /* Pad to 56 bytes mod 64. */ md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); + for (i = 0; i < 16; ++i) { + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); + } } class DefaultMD5Context : public HashContext { public: - DefaultMD5Context(Provider *p) : HashContext(p, "md5") - { - clear(); - } - - virtual Provider::Context *clone() const - { - return new DefaultMD5Context(*this); - } - - virtual void clear() - { - secure = true; - md5_init(&md5); - } - - virtual void update(const MemoryRegion &in) - { - if(!in.isSecure()) - secure = false; - md5_append(&md5, (const md5_byte_t *)in.data(), in.size()); - } - - virtual MemoryRegion final() - { - if(secure) - { - SecureArray b(16, 0); - md5_finish(&md5, (md5_byte_t *)b.data()); - return b; - } - else - { - QByteArray b(16, 0); - md5_finish(&md5, (md5_byte_t *)b.data()); - return b; - } - } - - bool secure; - md5_state_t md5; + DefaultMD5Context(Provider *p) : HashContext(p, "md5") + { + clear(); + } + + virtual Provider::Context *clone() const + { + return new DefaultMD5Context(*this); + } + + virtual void clear() + { + secure = true; + md5_init(&md5); + } + + virtual void update(const MemoryRegion &in) + { + if (!in.isSecure()) { + secure = false; + } + md5_append(&md5, (const md5_byte_t *)in.data(), in.size()); + } + + virtual MemoryRegion final() + { + if (secure) { + SecureArray b(16, 0); + md5_finish(&md5, (md5_byte_t *)b.data()); + return b; + } else { + QByteArray b(16, 0); + md5_finish(&md5, (md5_byte_t *)b.data()); + return b; + } + } + + bool secure; + md5_state_t md5; }; //---------------------------------------------------------------------------- @@ -577,213 +581,212 @@ #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); -struct SHA1_CONTEXT -{ - quint32 state[5]; // 5 - quint32 count[2]; // 2 - unsigned char buffer[64]; // 64 - - SHA1_CONTEXT() - { - memset(state, 0, 5 * sizeof(quint32)); - memset(count, 0, 2 * sizeof(quint32)); - memset(buffer, 0, 64 * sizeof(unsigned char)); - } - - SHA1_CONTEXT(const SHA1_CONTEXT &from) - { - *this = from; - } - - SHA1_CONTEXT & operator=(const SHA1_CONTEXT &from) - { - *this = from; - return *this; - } +struct SHA1_CONTEXT { + quint32 state[5]; // 5 + quint32 count[2]; // 2 + unsigned char buffer[64]; // 64 + + SHA1_CONTEXT() + { + memset(state, 0, 5 * sizeof(quint32)); + memset(count, 0, 2 * sizeof(quint32)); + memset(buffer, 0, 64 * sizeof(unsigned char)); + } + + SHA1_CONTEXT(const SHA1_CONTEXT &from) + { + *this = from; + } + + SHA1_CONTEXT &operator=(const SHA1_CONTEXT &from) + { + *this = from; + return *this; + } }; typedef union { - unsigned char c[64]; - quint32 l[16]; + unsigned char c[64]; + quint32 l[16]; } CHAR64LONG16; class DefaultSHA1Context : public HashContext { public: - SHA1_CONTEXT _context; + SHA1_CONTEXT _context; #ifdef Q_PROCESSOR_ARM - CHAR64LONG16 block; + CHAR64LONG16 block; #else - CHAR64LONG16 *block; + CHAR64LONG16 *block; #endif - bool secure; - - DefaultSHA1Context(Provider *p) : HashContext(p, "sha1") - { - clear(); - } - - virtual Provider::Context *clone() const - { - return new DefaultSHA1Context(*this); - } - - virtual void clear() - { - secure = true; - sha1_init(&_context); - } - - virtual void update(const MemoryRegion &in) - { - if(!in.isSecure()) - secure = false; - sha1_update(&_context, (unsigned char *)in.data(), (unsigned int)in.size()); - } - - virtual MemoryRegion final() - { - if(secure) - { - SecureArray b(20, 0); - sha1_final((unsigned char *)b.data(), &_context); - return b; - } - else - { - QByteArray b(20, 0); - sha1_final((unsigned char *)b.data(), &_context); - return b; - } - } - - inline unsigned long blk0(quint32 i) - { - if(QSysInfo::ByteOrder == QSysInfo::BigEndian) + bool secure; + + DefaultSHA1Context(Provider *p) : HashContext(p, "sha1") + { + clear(); + } + + virtual Provider::Context *clone() const + { + return new DefaultSHA1Context(*this); + } + + virtual void clear() + { + secure = true; + sha1_init(&_context); + } + + virtual void update(const MemoryRegion &in) + { + if (!in.isSecure()) { + secure = false; + } + sha1_update(&_context, (unsigned char *)in.data(), (unsigned int)in.size()); + } + + virtual MemoryRegion final() + { + if (secure) { + SecureArray b(20, 0); + sha1_final((unsigned char *)b.data(), &_context); + return b; + } else { + QByteArray b(20, 0); + sha1_final((unsigned char *)b.data(), &_context); + return b; + } + } + + inline unsigned long blk0(quint32 i) + { + if (QSysInfo::ByteOrder == QSysInfo::BigEndian) #ifdef Q_PROCESSOR_ARM - return block.l[i]; + return block.l[i]; #else - return block->l[i]; + return block->l[i]; #endif - else + else #ifdef Q_PROCESSOR_ARM - return (block.l[i] = (rol(block.l[i],24)&0xFF00FF00) | (rol(block.l[i],8)&0x00FF00FF)); + return (block.l[i] = (rol(block.l[i], 24) & 0xFF00FF00) | (rol(block.l[i], 8) & 0x00FF00FF)); #else - return (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF)); + return (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF)); #endif - } + } - // Hash a single 512-bit block. This is the core of the algorithm. - void transform(quint32 state[5], unsigned char buffer[64]) - { - quint32 a, b, c, d, e; + // Hash a single 512-bit block. This is the core of the algorithm. + void transform(quint32 state[5], unsigned char buffer[64]) + { + quint32 a, b, c, d, e; #ifdef Q_PROCESSOR_ARM - memcpy(&block, buffer, sizeof(block)); + memcpy(&block, buffer, sizeof(block)); #else - block = reinterpret_cast(buffer); + block = reinterpret_cast(buffer); #endif - // Copy context->state[] to working vars - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - - // 4 rounds of 20 operations each. Loop unrolled. - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - - // Add the working vars back into context.state[] - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - - // Wipe variables - a = b = c = d = e = 0; - } - - // SHA1Init - Initialize new context - void sha1_init(SHA1_CONTEXT* context) - { - // SHA1 initialization constants - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; - } - - // Run your data through this - void sha1_update(SHA1_CONTEXT* context, unsigned char* data, quint32 len) - { - quint32 i, j; - - j = (context->count[0] >> 3) & 63; - if((context->count[0] += len << 3) < (len << 3)) - context->count[1]++; - - context->count[1] += (len >> 29); - - if((j + len) > 63) { - memcpy(&context->buffer[j], data, (i = 64-j)); - transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) { - transform(context->state, &data[i]); - } - j = 0; - } - else i = 0; - memcpy(&context->buffer[j], &data[i], len - i); - } - - // Add padding and return the message digest - void sha1_final(unsigned char digest[20], SHA1_CONTEXT* context) - { - quint32 i; - unsigned char finalcount[8]; - - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); // Endian independent - } - sha1_update(context, (unsigned char *)"\200", 1); - while ((context->count[0] & 504) != 448) { - sha1_update(context, (unsigned char *)"\0", 1); - } - sha1_update(context, finalcount, 8); // Should cause a transform() - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - - // Wipe variables - i = 0; - memset(context->buffer, 0, 64); - memset(context->state, 0, 20); - memset(context->count, 0, 8); - memset(&finalcount, 0, 8); - } + // Copy context->state[] to working vars + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + + // 4 rounds of 20 operations each. Loop unrolled. + R0(a, b, c, d, e, 0); R0(e, a, b, c, d, 1); R0(d, e, a, b, c, 2); R0(c, d, e, a, b, 3); + R0(b, c, d, e, a, 4); R0(a, b, c, d, e, 5); R0(e, a, b, c, d, 6); R0(d, e, a, b, c, 7); + R0(c, d, e, a, b, 8); R0(b, c, d, e, a, 9); R0(a, b, c, d, e, 10); R0(e, a, b, c, d, 11); + R0(d, e, a, b, c, 12); R0(c, d, e, a, b, 13); R0(b, c, d, e, a, 14); R0(a, b, c, d, e, 15); + R1(e, a, b, c, d, 16); R1(d, e, a, b, c, 17); R1(c, d, e, a, b, 18); R1(b, c, d, e, a, 19); + R2(a, b, c, d, e, 20); R2(e, a, b, c, d, 21); R2(d, e, a, b, c, 22); R2(c, d, e, a, b, 23); + R2(b, c, d, e, a, 24); R2(a, b, c, d, e, 25); R2(e, a, b, c, d, 26); R2(d, e, a, b, c, 27); + R2(c, d, e, a, b, 28); R2(b, c, d, e, a, 29); R2(a, b, c, d, e, 30); R2(e, a, b, c, d, 31); + R2(d, e, a, b, c, 32); R2(c, d, e, a, b, 33); R2(b, c, d, e, a, 34); R2(a, b, c, d, e, 35); + R2(e, a, b, c, d, 36); R2(d, e, a, b, c, 37); R2(c, d, e, a, b, 38); R2(b, c, d, e, a, 39); + R3(a, b, c, d, e, 40); R3(e, a, b, c, d, 41); R3(d, e, a, b, c, 42); R3(c, d, e, a, b, 43); + R3(b, c, d, e, a, 44); R3(a, b, c, d, e, 45); R3(e, a, b, c, d, 46); R3(d, e, a, b, c, 47); + R3(c, d, e, a, b, 48); R3(b, c, d, e, a, 49); R3(a, b, c, d, e, 50); R3(e, a, b, c, d, 51); + R3(d, e, a, b, c, 52); R3(c, d, e, a, b, 53); R3(b, c, d, e, a, 54); R3(a, b, c, d, e, 55); + R3(e, a, b, c, d, 56); R3(d, e, a, b, c, 57); R3(c, d, e, a, b, 58); R3(b, c, d, e, a, 59); + R4(a, b, c, d, e, 60); R4(e, a, b, c, d, 61); R4(d, e, a, b, c, 62); R4(c, d, e, a, b, 63); + R4(b, c, d, e, a, 64); R4(a, b, c, d, e, 65); R4(e, a, b, c, d, 66); R4(d, e, a, b, c, 67); + R4(c, d, e, a, b, 68); R4(b, c, d, e, a, 69); R4(a, b, c, d, e, 70); R4(e, a, b, c, d, 71); + R4(d, e, a, b, c, 72); R4(c, d, e, a, b, 73); R4(b, c, d, e, a, 74); R4(a, b, c, d, e, 75); + R4(e, a, b, c, d, 76); R4(d, e, a, b, c, 77); R4(c, d, e, a, b, 78); R4(b, c, d, e, a, 79); + + // Add the working vars back into context.state[] + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + + // Wipe variables + a = b = c = d = e = 0; + } + + // SHA1Init - Initialize new context + void sha1_init(SHA1_CONTEXT *context) + { + // SHA1 initialization constants + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; + } + + // Run your data through this + void sha1_update(SHA1_CONTEXT *context, unsigned char *data, quint32 len) + { + quint32 i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) { + context->count[1]++; + } + + context->count[1] += (len >> 29); + + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64 - j)); + transform(context->state, context->buffer); + for (; i + 63 < len; i += 64) { + transform(context->state, &data[i]); + } + j = 0; + } else { + i = 0; + } + memcpy(&context->buffer[j], &data[i], len - i); + } + + // Add padding and return the message digest + void sha1_final(unsigned char digest[20], SHA1_CONTEXT *context) + { + quint32 i; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3 - (i & 3)) * 8)) & 255); // Endian independent + } + sha1_update(context, (unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) { + sha1_update(context, (unsigned char *)"\0", 1); + } + sha1_update(context, finalcount, 8); // Should cause a transform() + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + } + + // Wipe variables + i = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); + } }; //---------------------------------------------------------------------------- @@ -795,73 +798,74 @@ // single line of text. static QString escape_string(const QString &in) { - QString out; - for(int n = 0; n < in.length(); ++n) - { - if(in[n] == '\\') - out += "\\\\"; - else if(in[n] == ':') - out += "\\c"; - else if(in[n] == ',') - out += "\\o"; - else if(in[n] == '\n') - out += "\\n"; - else - out += in[n]; - } - return out; + QString out; + for (int n = 0; n < in.length(); ++n) { + if (in[n] == '\\') { + out += "\\\\"; + } else if (in[n] == ':') { + out += "\\c"; + } else if (in[n] == ',') { + out += "\\o"; + } else if (in[n] == '\n') { + out += "\\n"; + } else { + out += in[n]; + } + } + return out; } static bool unescape_string(const QString &in, QString *_out) { - QString out; - for(int n = 0; n < in.length(); ++n) - { - if(in[n] == '\\') - { - if(n + 1 >= in.length()) - return false; - - if(in[n + 1] == '\\') - out += '\\'; - else if(in[n + 1] == 'c') - out += ':'; - else if(in[n + 1] == 'o') - out += ','; - else if(in[n + 1] == 'n') - out += '\n'; - else - return false; - ++n; - } - else - out += in[n]; - } - *_out = out; - return true; + QString out; + for (int n = 0; n < in.length(); ++n) { + if (in[n] == '\\') { + if (n + 1 >= in.length()) { + return false; + } + + if (in[n + 1] == '\\') { + out += '\\'; + } else if (in[n + 1] == 'c') { + out += ':'; + } else if (in[n + 1] == 'o') { + out += ','; + } else if (in[n + 1] == 'n') { + out += '\n'; + } else { + return false; + } + ++n; + } else { + out += in[n]; + } + } + *_out = out; + return true; } static QString escape_stringlist(const QStringList &in) { - QStringList list; - for(int n = 0; n < in.count(); ++n) - list += escape_string(in[n]); - return list.join(":"); + QStringList list; + for (int n = 0; n < in.count(); ++n) { + list += escape_string(in[n]); + } + return list.join(":"); } static bool unescape_stringlist(const QString &in, QStringList *_out) { - QStringList out; - QStringList list = in.split(':'); - for(int n = 0; n < list.count(); ++n) - { - QString str; - if(!unescape_string(list[n], &str)) - return false; - out += str; - } - *_out = out; - return true; + QStringList out; + QStringList list = in.split(':'); + for (int n = 0; n < list.count(); ++n) { + QString str; + if (!unescape_string(list[n], &str)) { + return false; + } + out += str; + } + *_out = out; + return true; } // serialization format is a colon separated list of 7 escaped strings @@ -874,450 +878,449 @@ // 6 - string encoding of object (e.g. DER encoded in Base64) static QString entry_serialize(const QString &storeId, const QString &storeName, const QString &entryId, const QString &entryName, const QString &entryType, const QString &data) { - QStringList out; - out += "qca_def"; - out += storeId; - out += storeName; - out += entryId; - out += entryName; - out += entryType; - out += data; - return escape_stringlist(out); + QStringList out; + out += "qca_def"; + out += storeId; + out += storeName; + out += entryId; + out += entryName; + out += entryType; + out += data; + return escape_stringlist(out); } static bool entry_deserialize(const QString &in, QString *storeId, QString *storeName, QString *entryId, QString *entryName, QString *entryType, QString *data) { - QStringList list; - if(!unescape_stringlist(in, &list)) - return false; - if(list.count() != 7) - return false; - if(list[0] != "qca_def") - return false; - *storeId = list[1]; - *storeName = list[2]; - *entryId = list[3]; - *entryName = list[4]; - *entryType = list[5]; - *data = list[6]; - return true; + QStringList list; + if (!unescape_stringlist(in, &list)) { + return false; + } + if (list.count() != 7) { + return false; + } + if (list[0] != "qca_def") { + return false; + } + *storeId = list[1]; + *storeName = list[2]; + *entryId = list[3]; + *entryName = list[4]; + *entryType = list[5]; + *data = list[6]; + return true; } class DefaultKeyStoreEntry : public KeyStoreEntryContext { public: - KeyStoreEntry::Type _type; - QString _id, _name, _storeId, _storeName; - Certificate _cert; - CRL _crl; - mutable QString _serialized; - - DefaultKeyStoreEntry(const Certificate &cert, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p) - { - _type = KeyStoreEntry::TypeCertificate; - _storeId = storeId; - _storeName = storeName; - _cert = cert; - } - - DefaultKeyStoreEntry(const CRL &crl, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p) - { - _type = KeyStoreEntry::TypeCRL; - _storeId = storeId; - _storeName = storeName; - _crl = crl; - } - - virtual Provider::Context *clone() const - { - return new DefaultKeyStoreEntry(*this); - } - - virtual KeyStoreEntry::Type type() const - { - return _type; - } - - virtual QString id() const - { - return _id; - } - - virtual QString name() const - { - return _name; - } - - virtual QString storeId() const - { - return _storeId; - } - - virtual QString storeName() const - { - return _storeName; - } - - virtual Certificate certificate() const - { - return _cert; - } - - virtual CRL crl() const - { - return _crl; - } - - virtual QString serialize() const - { - if(_serialized.isEmpty()) - { - QString typestr; - QString datastr; - - if(_type == KeyStoreEntry::TypeCertificate) - { - typestr = "cert"; - datastr = Base64().arrayToString(_cert.toDER()); - } - else - { - typestr = "crl"; - datastr = Base64().arrayToString(_crl.toDER()); - } - - _serialized = entry_serialize(_storeId, _storeName, _id, _name, typestr, datastr); - } - - return _serialized; - } - - static DefaultKeyStoreEntry *deserialize(const QString &in, Provider *provider) - { - QString storeId, storeName, id, name, typestr, datastr; - - if(entry_deserialize(in, &storeId, &storeName, &id, &name, &typestr, &datastr)) - { - QByteArray data = Base64().stringToArray(datastr).toByteArray(); - DefaultKeyStoreEntry *c; - - if(typestr == "cert") - { - Certificate cert = Certificate::fromDER(data); - if(cert.isNull()) - return 0; - c = new DefaultKeyStoreEntry(cert, storeId, storeName, provider); - } - else if(typestr == "crl") - { - CRL crl = CRL::fromDER(data); - if(crl.isNull()) - return 0; - c = new DefaultKeyStoreEntry(crl, storeId, storeName, provider); - } - else - return 0; - - c->_id = id; - c->_name = name; - c->_serialized = in; - return c; - } - return 0; - } - - QString simpleId() const - { - if(_type == KeyStoreEntry::TypeCertificate) - return QString::number(qHash(_cert.toDER())); - else - return QString::number(qHash(_crl.toDER())); - } - - QString simpleName() const - { - // use the common name, else orgname - if(_type == KeyStoreEntry::TypeCertificate) - { - QString str = _cert.commonName(); - if(str.isEmpty()) - str = _cert.subjectInfo().value(Organization); - return str; - } - else - return _crl.issuerInfo().value(CommonName); - } + KeyStoreEntry::Type _type; + QString _id, _name, _storeId, _storeName; + Certificate _cert; + CRL _crl; + mutable QString _serialized; + + DefaultKeyStoreEntry(const Certificate &cert, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p) + { + _type = KeyStoreEntry::TypeCertificate; + _storeId = storeId; + _storeName = storeName; + _cert = cert; + } + + DefaultKeyStoreEntry(const CRL &crl, const QString &storeId, const QString &storeName, Provider *p) : KeyStoreEntryContext(p) + { + _type = KeyStoreEntry::TypeCRL; + _storeId = storeId; + _storeName = storeName; + _crl = crl; + } + + virtual Provider::Context *clone() const + { + return new DefaultKeyStoreEntry(*this); + } + + virtual KeyStoreEntry::Type type() const + { + return _type; + } + + virtual QString id() const + { + return _id; + } + + virtual QString name() const + { + return _name; + } + + virtual QString storeId() const + { + return _storeId; + } + + virtual QString storeName() const + { + return _storeName; + } + + virtual Certificate certificate() const + { + return _cert; + } + + virtual CRL crl() const + { + return _crl; + } + + virtual QString serialize() const + { + if (_serialized.isEmpty()) { + QString typestr; + QString datastr; + + if (_type == KeyStoreEntry::TypeCertificate) { + typestr = "cert"; + datastr = Base64().arrayToString(_cert.toDER()); + } else { + typestr = "crl"; + datastr = Base64().arrayToString(_crl.toDER()); + } + + _serialized = entry_serialize(_storeId, _storeName, _id, _name, typestr, datastr); + } + + return _serialized; + } + + static DefaultKeyStoreEntry *deserialize(const QString &in, Provider *provider) + { + QString storeId, storeName, id, name, typestr, datastr; + + if (entry_deserialize(in, &storeId, &storeName, &id, &name, &typestr, &datastr)) { + QByteArray data = Base64().stringToArray(datastr).toByteArray(); + DefaultKeyStoreEntry *c; + + if (typestr == "cert") { + Certificate cert = Certificate::fromDER(data); + if (cert.isNull()) { + return 0; + } + c = new DefaultKeyStoreEntry(cert, storeId, storeName, provider); + } else if (typestr == "crl") { + CRL crl = CRL::fromDER(data); + if (crl.isNull()) { + return 0; + } + c = new DefaultKeyStoreEntry(crl, storeId, storeName, provider); + } else { + return 0; + } + + c->_id = id; + c->_name = name; + c->_serialized = in; + return c; + } + return 0; + } + + QString simpleId() const + { + if (_type == KeyStoreEntry::TypeCertificate) { + return QString::number(qHash(_cert.toDER())); + } else { + return QString::number(qHash(_crl.toDER())); + } + } + + QString simpleName() const + { + // use the common name, else orgname + if (_type == KeyStoreEntry::TypeCertificate) { + QString str = _cert.commonName(); + if (str.isEmpty()) { + str = _cert.subjectInfo().value(Organization); + } + return str; + } else { + return _crl.issuerInfo().value(CommonName); + } + } }; //---------------------------------------------------------------------------- // DefaultKeyStoreList //---------------------------------------------------------------------------- class DefaultKeyStoreList : public KeyStoreListContext { - Q_OBJECT + Q_OBJECT public: - bool x509_supported; - DefaultShared *shared; - - DefaultKeyStoreList(Provider *p, DefaultShared *_shared) : KeyStoreListContext(p), shared(_shared) - { - } - - ~DefaultKeyStoreList() - { - } - - virtual Provider::Context *clone() const - { - return 0; - } - - virtual void start() - { - x509_supported = false; - - QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection); - } - - virtual QList keyStores() - { - if(!x509_supported) - { - if(isSupported("cert") && isSupported("crl")) - x509_supported = true; - } - - bool have_systemstore = false; + bool x509_supported; + DefaultShared *shared; + + DefaultKeyStoreList(Provider *p, DefaultShared *_shared) : KeyStoreListContext(p), shared(_shared) + { + } + + ~DefaultKeyStoreList() + { + } + + virtual Provider::Context *clone() const + { + return 0; + } + + virtual void start() + { + x509_supported = false; + + QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection); + } + + virtual QList keyStores() + { + if (!x509_supported) { + if (isSupported("cert") && isSupported("crl")) { + x509_supported = true; + } + } + + bool have_systemstore = false; #ifndef QCA_NO_SYSTEMSTORE - if(shared->use_system()) - have_systemstore = qca_have_systemstore(); + if (shared->use_system()) { + have_systemstore = qca_have_systemstore(); + } #endif - QList list; - - // system store only shows up if the OS store is available or - // there is a configured store file - if(x509_supported && (have_systemstore || !shared->roots_file().isEmpty())) - list += 0; - - return list; - } - - virtual KeyStore::Type type(int) const - { - return KeyStore::System; - } - - virtual QString storeId(int) const - { - return "qca-default-systemstore"; - } - - virtual QString name(int) const - { - return "System Trusted Certificates"; - } - - virtual QList entryTypes(int) const - { - QList list; - list += KeyStoreEntry::TypeCertificate; - list += KeyStoreEntry::TypeCRL; - return list; - } - - virtual QList entryList(int) - { - QList out; - - QList certs; - QList crls; - - if(shared->use_system()) - { - CertificateCollection col; + QList list; + + // system store only shows up if the OS store is available or + // there is a configured store file + if (x509_supported && (have_systemstore || !shared->roots_file().isEmpty())) { + list += 0; + } + + return list; + } + + virtual KeyStore::Type type(int) const + { + return KeyStore::System; + } + + virtual QString storeId(int) const + { + return "qca-default-systemstore"; + } + + virtual QString name(int) const + { + return "System Trusted Certificates"; + } + + virtual QList entryTypes(int) const + { + QList list; + list += KeyStoreEntry::TypeCertificate; + list += KeyStoreEntry::TypeCRL; + return list; + } + + virtual QList entryList(int) + { + QList out; + + QList certs; + QList crls; + + if (shared->use_system()) { + CertificateCollection col; #ifndef QCA_NO_SYSTEMSTORE - col = qca_get_systemstore(QString()); + col = qca_get_systemstore(QString()); #endif - certs += col.certificates(); - crls += col.crls(); - } - - QString roots = shared->roots_file(); - if(!roots.isEmpty()) - { - CertificateCollection col = CertificateCollection::fromFlatTextFile(roots); - certs += col.certificates(); - crls += col.crls(); - } + certs += col.certificates(); + crls += col.crls(); + } + + QString roots = shared->roots_file(); + if (!roots.isEmpty()) { + CertificateCollection col = CertificateCollection::fromFlatTextFile(roots); + certs += col.certificates(); + crls += col.crls(); + } #ifdef FRIENDLY_NAMES - QStringList names = makeFriendlyNames(certs); + QStringList names = makeFriendlyNames(certs); #endif - for(int n = 0; n < certs.count(); ++n) - { - DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(certs[n], storeId(0), name(0), provider()); - c->_id = c->simpleId(); + for (int n = 0; n < certs.count(); ++n) { + DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(certs[n], storeId(0), name(0), provider()); + c->_id = c->simpleId(); #ifdef FRIENDLY_NAMES - c->_name = names[n]; + c->_name = names[n]; #else - c->_name = c->simpleName(); + c->_name = c->simpleName(); #endif - out.append(c); - } - - for(int n = 0; n < crls.count(); ++n) - { - DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(crls[n], storeId(0), name(0), provider()); - c->_id = c->simpleId(); - c->_name = c->simpleName(); - out.append(c); - } - - return out; - } - - virtual KeyStoreEntryContext *entryPassive(const QString &serialized) - { - return DefaultKeyStoreEntry::deserialize(serialized, provider()); - } + out.append(c); + } + + for (int n = 0; n < crls.count(); ++n) { + DefaultKeyStoreEntry *c = new DefaultKeyStoreEntry(crls[n], storeId(0), name(0), provider()); + c->_id = c->simpleId(); + c->_name = c->simpleName(); + out.append(c); + } + + return out; + } + + virtual KeyStoreEntryContext *entryPassive(const QString &serialized) + { + return DefaultKeyStoreEntry::deserialize(serialized, provider()); + } }; //---------------------------------------------------------------------------- // DefaultProvider //---------------------------------------------------------------------------- static bool unescape_config_stringlist(const QString &in, QStringList *_out) { - QStringList out; - QStringList list = in.split(','); - for(int n = 0; n < list.count(); ++n) - { - QString str; - if(!unescape_string(list[n], &str)) - return false; - out += str.trimmed(); - } - *_out = out; - return true; + QStringList out; + QStringList list = in.split(','); + for (int n = 0; n < list.count(); ++n) { + QString str; + if (!unescape_string(list[n], &str)) { + return false; + } + out += str.trimmed(); + } + *_out = out; + return true; } class DefaultProvider : public Provider { public: - DefaultShared shared; - - virtual void init() - { - QDateTime now = QDateTime::currentDateTime(); - - uint t = now.toTime_t(); - if(now.time().msec() > 0) - t /= now.time().msec(); - qsrand(t); - } - - virtual int version() const - { - return QCA_VERSION; - } - - virtual int qcaVersion() const - { - return QCA_VERSION; - } - - virtual QString name() const - { - return "default"; - } - - virtual QStringList features() const - { - QStringList list; - list += "random"; - list += "md5"; - list += "sha1"; - list += "keystorelist"; - return list; - } - - virtual Provider::Context *createContext(const QString &type) - { - if(type == "random") - return new DefaultRandomContext(this); - else if(type == "md5") - return new DefaultMD5Context(this); - else if(type == "sha1") - return new DefaultSHA1Context(this); - else if(type == "keystorelist") - return new DefaultKeyStoreList(this, &shared); - else - return 0; - } - - virtual QVariantMap defaultConfig() const - { - QVariantMap config; - config["formtype"] = "http://affinix.com/qca/forms/default#1.0"; - config["use_system"] = true; - config["roots_file"] = QString(); - config["skip_plugins"] = QString(); - config["plugin_priorities"] = QString(); - return config; - } - - virtual void configChanged(const QVariantMap &config) - { - bool use_system = config["use_system"].toBool(); - QString roots_file = config["roots_file"].toString(); - QString skip_plugins_str = config["skip_plugins"].toString(); - QString plugin_priorities_str = config["plugin_priorities"].toString(); - - QStringList tmp; - - QStringList skip_plugins; - if(unescape_config_stringlist(skip_plugins_str, &tmp)) - skip_plugins = tmp; - - QStringList plugin_priorities; - if(unescape_config_stringlist(plugin_priorities_str, &tmp)) - plugin_priorities = tmp; - - for(int n = 0; n < plugin_priorities.count(); ++n) - { - QString &s = plugin_priorities[n]; - - // make sure the entry ends with ":number" - int x = s.indexOf(':'); - bool ok = false; - if(x != -1) - s.mid(x + 1).toInt(&ok); - if(!ok) - { - plugin_priorities.removeAt(n); - --n; - } - } - - shared.set(use_system, roots_file, skip_plugins, plugin_priorities); - } + DefaultShared shared; + + virtual void init() + { + QDateTime now = QDateTime::currentDateTime(); + + uint t = now.toTime_t(); + if (now.time().msec() > 0) { + t /= now.time().msec(); + } + qsrand(t); + } + + virtual int version() const + { + return QCA_VERSION; + } + + virtual int qcaVersion() const + { + return QCA_VERSION; + } + + virtual QString name() const + { + return "default"; + } + + virtual QStringList features() const + { + QStringList list; + list += "random"; + list += "md5"; + list += "sha1"; + list += "keystorelist"; + return list; + } + + virtual Provider::Context *createContext(const QString &type) + { + if (type == "random") { + return new DefaultRandomContext(this); + } else if (type == "md5") { + return new DefaultMD5Context(this); + } else if (type == "sha1") { + return new DefaultSHA1Context(this); + } else if (type == "keystorelist") { + return new DefaultKeyStoreList(this, &shared); + } else { + return 0; + } + } + + virtual QVariantMap defaultConfig() const + { + QVariantMap config; + config["formtype"] = "http://affinix.com/qca/forms/default#1.0"; + config["use_system"] = true; + config["roots_file"] = QString(); + config["skip_plugins"] = QString(); + config["plugin_priorities"] = QString(); + return config; + } + + virtual void configChanged(const QVariantMap &config) + { + bool use_system = config["use_system"].toBool(); + QString roots_file = config["roots_file"].toString(); + QString skip_plugins_str = config["skip_plugins"].toString(); + QString plugin_priorities_str = config["plugin_priorities"].toString(); + + QStringList tmp; + + QStringList skip_plugins; + if (unescape_config_stringlist(skip_plugins_str, &tmp)) { + skip_plugins = tmp; + } + + QStringList plugin_priorities; + if (unescape_config_stringlist(plugin_priorities_str, &tmp)) { + plugin_priorities = tmp; + } + + for (int n = 0; n < plugin_priorities.count(); ++n) { + QString &s = plugin_priorities[n]; + + // make sure the entry ends with ":number" + int x = s.indexOf(':'); + bool ok = false; + if (x != -1) { + s.mid(x + 1).toInt(&ok); + } + if (!ok) { + plugin_priorities.removeAt(n); + --n; + } + } + + shared.set(use_system, roots_file, skip_plugins, plugin_priorities); + } }; Provider *create_default_provider() { - return new DefaultProvider; + return new DefaultProvider; } QStringList skip_plugins(Provider *defaultProvider) { - DefaultProvider *that = (DefaultProvider *)defaultProvider; - return that->shared.skip_plugins(); + DefaultProvider *that = (DefaultProvider *)defaultProvider; + return that->shared.skip_plugins(); } QStringList plugin_priorities(Provider *defaultProvider) { - DefaultProvider *that = (DefaultProvider *)defaultProvider; - return that->shared.plugin_priorities(); + DefaultProvider *that = (DefaultProvider *)defaultProvider; + return that->shared.plugin_priorities(); } #include "qca_default.moc" diff --git a/src/qca_keystore.cpp b/src/qca_keystore.cpp --- a/src/qca_keystore.cpp +++ b/src/qca_keystore.cpp @@ -41,7 +41,8 @@ Q_DECLARE_METATYPE(QCA::CRL) Q_DECLARE_METATYPE(QCA::PGPKey) -namespace QCA { +namespace QCA +{ Provider::Context *getContext(const QString &type, Provider *p); @@ -83,520 +84,516 @@ class KeyStoreTracker : public QObject { - Q_OBJECT + Q_OBJECT public: - static KeyStoreTracker *self; - - class Item - { - public: - // combine keystore owner and contextid into a single id - int trackerId; - - // number of times the keystore has been updated - int updateCount; - - // keystore context - KeyStoreListContext *owner; - int storeContextId; - - // properties - QString storeId; - QString name; - KeyStore::Type type; - bool isReadOnly; - - Item() - : trackerId(-1) - , updateCount(0) - , owner(0) - , storeContextId(-1) - , storeId("") - , name("") - , type(KeyStore::System) - , isReadOnly(false) - { - } - }; - - QMutex m; - QSet sources; - QSet busySources; - QList items; - QString dtext; - bool startedAll; - bool busy; - - QMutex updateMutex; - - KeyStoreTracker() - { - self = this; - - qRegisterMetaType(); - qRegisterMetaType< QList >(); - qRegisterMetaType< QList >(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - qRegisterMetaType(); - - connect(this, SIGNAL(updated_p()), SLOT(updated_locked()), Qt::QueuedConnection); - - startedAll = false; - busy = true; // we start out busy - } - - ~KeyStoreTracker() - { - qDeleteAll(sources); - self = 0; - } - - static KeyStoreTracker *instance() - { - return self; - } - - // thread-safe - bool isBusy() - { - QMutexLocker locker(&m); - return busy; - } - - // thread-safe - QList getItems() - { - QMutexLocker locker(&m); - return items; - } - - // thread-safe - QString getDText() - { - QMutexLocker locker(&m); - return dtext; - } - - // thread-safe - void clearDText() - { - QMutexLocker locker(&m); - dtext.clear(); - } - - // thread-safe - void addTarget(QObject *ksm) - { - QMutexLocker locker(&updateMutex); - ksm->connect(this, SIGNAL(updated()), SLOT(tracker_updated()), Qt::DirectConnection); - } - - // thread-safe - void removeTarget(QObject *ksm) - { - QMutexLocker locker(&updateMutex); - disconnect(ksm); - } + static KeyStoreTracker *self; + + class Item + { + public: + // combine keystore owner and contextid into a single id + int trackerId; + + // number of times the keystore has been updated + int updateCount; + + // keystore context + KeyStoreListContext *owner; + int storeContextId; + + // properties + QString storeId; + QString name; + KeyStore::Type type; + bool isReadOnly; + + Item() + : trackerId(-1) + , updateCount(0) + , owner(0) + , storeContextId(-1) + , storeId("") + , name("") + , type(KeyStore::System) + , isReadOnly(false) + { + } + }; + + QMutex m; + QSet sources; + QSet busySources; + QList items; + QString dtext; + bool startedAll; + bool busy; + + QMutex updateMutex; + + KeyStoreTracker() + { + self = this; + + qRegisterMetaType(); + qRegisterMetaType< QList >(); + qRegisterMetaType< QList >(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); + + connect(this, SIGNAL(updated_p()), SLOT(updated_locked()), Qt::QueuedConnection); + + startedAll = false; + busy = true; // we start out busy + } + + ~KeyStoreTracker() + { + qDeleteAll(sources); + self = 0; + } + + static KeyStoreTracker *instance() + { + return self; + } + + // thread-safe + bool isBusy() + { + QMutexLocker locker(&m); + return busy; + } + + // thread-safe + QList getItems() + { + QMutexLocker locker(&m); + return items; + } + + // thread-safe + QString getDText() + { + QMutexLocker locker(&m); + return dtext; + } + + // thread-safe + void clearDText() + { + QMutexLocker locker(&m); + dtext.clear(); + } + + // thread-safe + void addTarget(QObject *ksm) + { + QMutexLocker locker(&updateMutex); + ksm->connect(this, SIGNAL(updated()), SLOT(tracker_updated()), Qt::DirectConnection); + } + + // thread-safe + void removeTarget(QObject *ksm) + { + QMutexLocker locker(&updateMutex); + disconnect(ksm); + } public slots: - void spinEventLoop() - { - QAbstractEventDispatcher::instance()->processEvents(QEventLoop::AllEvents); - } - - void start() - { - // grab providers (and default) - ProviderList list = providers(); - list.append(defaultProvider()); - - for(int n = 0; n < list.count(); ++n) - { - Provider *p = list[n]; - if(p->features().contains("keystorelist") && !haveProviderSource(p)) - startProvider(p); - } - - startedAll = true; - } - - void start(const QString &provider) - { - // grab providers (and default) - ProviderList list = providers(); - list.append(defaultProvider()); - - Provider *p = 0; - for(int n = 0; n < list.count(); ++n) - { - if(list[n]->name() == provider) - { - p = list[n]; - break; - } - } - - if(p && p->features().contains("keystorelist") && !haveProviderSource(p)) - startProvider(p); - } - - void scan() - { - if(startedAll) - start(); - } - - QList entryList(int trackerId) - { - QList out; - int at = findItem(trackerId); - if(at == -1) - return out; - Item &i = items[at]; - QList list = i.owner->entryList(i.storeContextId); - for(int n = 0; n < list.count(); ++n) - { - KeyStoreEntry entry; - entry.change(list[n]); - out.append(entry); - } - return out; - } - - QList entryTypes(int trackerId) - { - QList out; - int at = findItem(trackerId); - if(at == -1) - return out; - Item &i = items[at]; - return i.owner->entryTypes(i.storeContextId); - } - - // hack with void * - void *entry(const QString &storeId, const QString &entryId) - { - KeyStoreListContext *c = 0; - int contextId = -1; - m.lock(); - foreach(const Item &i, items) - { - if(i.storeId == storeId) - { - c = i.owner; - contextId = i.storeContextId; - break; - } - } - m.unlock(); - if(!c) - return 0; - - return c->entry(contextId, entryId); - } - - // hack with void * - void *entryPassive(const QString &serialized) - { - foreach(KeyStoreListContext *ksl, sources) - { - // "is this yours?" - KeyStoreEntryContext *e = ksl->entryPassive(serialized); - if(e) - return e; - } - return 0; - } - - QString writeEntry(int trackerId, const QVariant &v) - { - int at = findItem(trackerId); - if(at == -1) - return QString(); - Item &i = items[at]; + void spinEventLoop() + { + QAbstractEventDispatcher::instance()->processEvents(QEventLoop::AllEvents); + } + + void start() + { + // grab providers (and default) + ProviderList list = providers(); + list.append(defaultProvider()); + + for (int n = 0; n < list.count(); ++n) { + Provider *p = list[n]; + if (p->features().contains("keystorelist") && !haveProviderSource(p)) { + startProvider(p); + } + } + + startedAll = true; + } + + void start(const QString &provider) + { + // grab providers (and default) + ProviderList list = providers(); + list.append(defaultProvider()); + + Provider *p = 0; + for (int n = 0; n < list.count(); ++n) { + if (list[n]->name() == provider) { + p = list[n]; + break; + } + } + + if (p && p->features().contains("keystorelist") && !haveProviderSource(p)) { + startProvider(p); + } + } + + void scan() + { + if (startedAll) { + start(); + } + } + + QList entryList(int trackerId) + { + QList out; + int at = findItem(trackerId); + if (at == -1) { + return out; + } + Item &i = items[at]; + QList list = i.owner->entryList(i.storeContextId); + for (int n = 0; n < list.count(); ++n) { + KeyStoreEntry entry; + entry.change(list[n]); + out.append(entry); + } + return out; + } + + QList entryTypes(int trackerId) + { + QList out; + int at = findItem(trackerId); + if (at == -1) { + return out; + } + Item &i = items[at]; + return i.owner->entryTypes(i.storeContextId); + } + + // hack with void * + void *entry(const QString &storeId, const QString &entryId) + { + KeyStoreListContext *c = 0; + int contextId = -1; + m.lock(); + foreach (const Item &i, items) { + if (i.storeId == storeId) { + c = i.owner; + contextId = i.storeContextId; + break; + } + } + m.unlock(); + if (!c) { + return 0; + } + + return c->entry(contextId, entryId); + } + + // hack with void * + void *entryPassive(const QString &serialized) + { + foreach (KeyStoreListContext *ksl, sources) { + // "is this yours?" + KeyStoreEntryContext *e = ksl->entryPassive(serialized); + if (e) { + return e; + } + } + return 0; + } + + QString writeEntry(int trackerId, const QVariant &v) + { + int at = findItem(trackerId); + if (at == -1) { + return QString(); + } + Item &i = items[at]; #if QT_VERSION >= 0x050000 - if(v.canConvert()) - return i.owner->writeEntry(i.storeContextId, v.value()); - else if(v.canConvert()) - return i.owner->writeEntry(i.storeContextId, v.value()); - else if(v.canConvert()) - return i.owner->writeEntry(i.storeContextId, v.value()); - else if(v.canConvert()) - return i.owner->writeEntry(i.storeContextId, v.value()); + if (v.canConvert()) { + return i.owner->writeEntry(i.storeContextId, v.value()); + } else if (v.canConvert()) { + return i.owner->writeEntry(i.storeContextId, v.value()); + } else if (v.canConvert()) { + return i.owner->writeEntry(i.storeContextId, v.value()); + } else if (v.canConvert()) { + return i.owner->writeEntry(i.storeContextId, v.value()); + } #else - if(qVariantCanConvert(v)) - return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); - else if(qVariantCanConvert(v)) - return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); - else if(qVariantCanConvert(v)) - return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); - else if(qVariantCanConvert(v)) - return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); + if (qVariantCanConvert(v)) { + return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); + } else if (qVariantCanConvert(v)) { + return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); + } else if (qVariantCanConvert(v)) { + return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); + } else if (qVariantCanConvert(v)) { + return i.owner->writeEntry(i.storeContextId, qVariantValue(v)); + } #endif - else - return QString(); - } - - QString writeEntry(int trackerId, const QCA::KeyBundle &v) - { - int at = findItem(trackerId); - if(at == -1) - return QString(); - Item &i = items[at]; - - return i.owner->writeEntry(i.storeContextId, v); - } - - QString writeEntry(int trackerId, const QCA::Certificate &v) - { - int at = findItem(trackerId); - if(at == -1) - return QString(); - Item &i = items[at]; - - return i.owner->writeEntry(i.storeContextId, v); - } - - QString writeEntry(int trackerId, const QCA::CRL &v) - { - int at = findItem(trackerId); - if(at == -1) - return QString(); - Item &i = items[at]; - - return i.owner->writeEntry(i.storeContextId, v); - } - - QString writeEntry(int trackerId, const QCA::PGPKey &v) - { - int at = findItem(trackerId); - if(at == -1) - return QString(); - Item &i = items[at]; - - return i.owner->writeEntry(i.storeContextId, v); - } - - bool removeEntry(int trackerId, const QString &entryId) - { - int at = findItem(trackerId); - if(at == -1) - return false; - Item &i = items[at]; - return i.owner->removeEntry(i.storeContextId, entryId); - } + else { + return QString(); + } + } + + QString writeEntry(int trackerId, const QCA::KeyBundle &v) + { + int at = findItem(trackerId); + if (at == -1) { + return QString(); + } + Item &i = items[at]; + + return i.owner->writeEntry(i.storeContextId, v); + } + + QString writeEntry(int trackerId, const QCA::Certificate &v) + { + int at = findItem(trackerId); + if (at == -1) { + return QString(); + } + Item &i = items[at]; + + return i.owner->writeEntry(i.storeContextId, v); + } + + QString writeEntry(int trackerId, const QCA::CRL &v) + { + int at = findItem(trackerId); + if (at == -1) { + return QString(); + } + Item &i = items[at]; + + return i.owner->writeEntry(i.storeContextId, v); + } + + QString writeEntry(int trackerId, const QCA::PGPKey &v) + { + int at = findItem(trackerId); + if (at == -1) { + return QString(); + } + Item &i = items[at]; + + return i.owner->writeEntry(i.storeContextId, v); + } + + bool removeEntry(int trackerId, const QString &entryId) + { + int at = findItem(trackerId); + if (at == -1) { + return false; + } + Item &i = items[at]; + return i.owner->removeEntry(i.storeContextId, entryId); + } signals: - // emit this when items or busy state changes - void updated(); - void updated_p(); + // emit this when items or busy state changes + void updated(); + void updated_p(); private slots: - void updated_locked() - { - QMutexLocker locker(&updateMutex); - emit updated(); - } + void updated_locked() + { + QMutexLocker locker(&updateMutex); + emit updated(); + } private: - bool haveProviderSource(Provider *p) const - { - foreach(KeyStoreListContext *ksl, sources) - { - if(ksl->provider() == p) - return true; - } - return false; - } - - int findItem(int trackerId) - { - for(int n = 0; n < items.count(); ++n) - { - if(items[n].trackerId == trackerId) - return n; - } - return -1; - } - - void startProvider(Provider *p) - { - KeyStoreListContext *c = static_cast(getContext("keystorelist", p)); - if(!c) - return; - - sources += c; - busySources += c; - connect(c, SIGNAL(busyStart()), SLOT(ksl_busyStart())); - connect(c, SIGNAL(busyEnd()), SLOT(ksl_busyEnd())); - connect(c, SIGNAL(updated()), SLOT(ksl_updated())); - connect(c, SIGNAL(diagnosticText(const QString &)), SLOT(ksl_diagnosticText(const QString &))); - connect(c, SIGNAL(storeUpdated(int)), SLOT(ksl_storeUpdated(int))); - c->start(); - c->setUpdatesEnabled(true); - - QCA_logTextMessage(QString("keystore: startProvider %1").arg(p->name()), Logger::Information); - } - - bool updateStores(KeyStoreListContext *c) - { - bool changed = false; - - QMutexLocker locker(&m); - - QList keyStores = c->keyStores(); - - // remove any contexts that are gone - for(int n = 0; n < items.count(); ++n) - { - if(items[n].owner == c && !keyStores.contains(items[n].storeContextId)) - { - QCA_logTextMessage(QString("keystore: updateStores remove %1").arg(items[n].storeContextId), Logger::Information); - - items.removeAt(n); - --n; // adjust position - - changed = true; - } - } - - // handle add/updates - foreach(int id, keyStores) - { - // do we have it already? - int at = -1; - for(int n = 0; n < items.count(); ++n) - { - if(items[n].owner == c && items[n].storeContextId == id) - { - at = n; - break; - } - } - - // if so, update it - if(at != -1) - { - Item &i = items[at]; - - QString name = c->name(id); - bool isReadOnly = c->isReadOnly(id); - if(i.name != name || i.isReadOnly != isReadOnly) - { - QCA_logTextMessage(QString("keystore: updateStores update %1").arg(id), Logger::Information); - i.name = name; - i.isReadOnly = isReadOnly; - changed = true; - } - } - // otherwise, add it - else - { - QCA_logTextMessage(QString("keystore: updateStores add %1").arg(id), Logger::Information); - - Item i; - i.trackerId = tracker_id_at++; - i.updateCount = 0; - i.owner = c; - i.storeContextId = id; - i.storeId = c->storeId(id); - i.name = c->name(id); - i.type = c->type(id); - i.isReadOnly = c->isReadOnly(id); - items += i; - - changed = true; - } - } - - return changed; - } + bool haveProviderSource(Provider *p) const + { + foreach (KeyStoreListContext *ksl, sources) { + if (ksl->provider() == p) { + return true; + } + } + return false; + } + + int findItem(int trackerId) + { + for (int n = 0; n < items.count(); ++n) { + if (items[n].trackerId == trackerId) { + return n; + } + } + return -1; + } + + void startProvider(Provider *p) + { + KeyStoreListContext *c = static_cast(getContext("keystorelist", p)); + if (!c) { + return; + } + + sources += c; + busySources += c; + connect(c, SIGNAL(busyStart()), SLOT(ksl_busyStart())); + connect(c, SIGNAL(busyEnd()), SLOT(ksl_busyEnd())); + connect(c, SIGNAL(updated()), SLOT(ksl_updated())); + connect(c, SIGNAL(diagnosticText(QString)), SLOT(ksl_diagnosticText(QString))); + connect(c, SIGNAL(storeUpdated(int)), SLOT(ksl_storeUpdated(int))); + c->start(); + c->setUpdatesEnabled(true); + + QCA_logTextMessage(QString("keystore: startProvider %1").arg(p->name()), Logger::Information); + } + + bool updateStores(KeyStoreListContext *c) + { + bool changed = false; + + QMutexLocker locker(&m); + + QList keyStores = c->keyStores(); + + // remove any contexts that are gone + for (int n = 0; n < items.count(); ++n) { + if (items[n].owner == c && !keyStores.contains(items[n].storeContextId)) { + QCA_logTextMessage(QString("keystore: updateStores remove %1").arg(items[n].storeContextId), Logger::Information); + + items.removeAt(n); + --n; // adjust position + + changed = true; + } + } + + // handle add/updates + foreach (int id, keyStores) { + // do we have it already? + int at = -1; + for (int n = 0; n < items.count(); ++n) { + if (items[n].owner == c && items[n].storeContextId == id) { + at = n; + break; + } + } + + // if so, update it + if (at != -1) { + Item &i = items[at]; + + QString name = c->name(id); + bool isReadOnly = c->isReadOnly(id); + if (i.name != name || i.isReadOnly != isReadOnly) { + QCA_logTextMessage(QString("keystore: updateStores update %1").arg(id), Logger::Information); + i.name = name; + i.isReadOnly = isReadOnly; + changed = true; + } + } + // otherwise, add it + else { + QCA_logTextMessage(QString("keystore: updateStores add %1").arg(id), Logger::Information); + + Item i; + i.trackerId = tracker_id_at++; + i.updateCount = 0; + i.owner = c; + i.storeContextId = id; + i.storeId = c->storeId(id); + i.name = c->name(id); + i.type = c->type(id); + i.isReadOnly = c->isReadOnly(id); + items += i; + + changed = true; + } + } + + return changed; + } private slots: - void ksl_busyStart() - { - KeyStoreListContext *c = (KeyStoreListContext *)sender(); - - QCA_logTextMessage(QString("keystore: ksl_busyStart %1").arg(c->provider()->name()), Logger::Information); - - if(!busySources.contains(c)) - { - busySources += c; - - QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); - emit updated_p(); - } - } - - void ksl_busyEnd() - { - KeyStoreListContext *c = (KeyStoreListContext *)sender(); - - QCA_logTextMessage(QString("keystore: ksl_busyEnd %1").arg(c->provider()->name()), Logger::Information); - - busySources.remove(c); - bool changed = updateStores(c); - bool any_busy = !busySources.isEmpty(); - - if(!any_busy) - { - m.lock(); - busy = false; - m.unlock(); - } - - if(!any_busy || changed) - { - QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); - emit updated_p(); - } - } - - void ksl_updated() - { - KeyStoreListContext *c = (KeyStoreListContext *)sender(); - - QCA_logTextMessage(QString("keystore: ksl_updated %1").arg(c->provider()->name()), Logger::Information); - - bool changed = updateStores(c); - if(changed) - { - QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); - emit updated_p(); - } - } - - void ksl_diagnosticText(const QString &str) - { - QMutexLocker locker(&m); - dtext += str; - dtext = truncate_log(dtext, 100000); - } - - void ksl_storeUpdated(int id) - { - KeyStoreListContext *c = (KeyStoreListContext *)sender(); - - QCA_logTextMessage(QString("keystore: ksl_storeUpdated %1 %2").arg(c->provider()->name(), QString::number(id)), Logger::Information); - - QMutexLocker locker(&m); - for(int n = 0; n < items.count(); ++n) - { - Item &i = items[n]; - if(i.owner == c && i.storeContextId == id) - { - ++i.updateCount; - - QCA_logTextMessage(QString("keystore: %1 updateCount = %2").arg(i.name, QString::number(i.updateCount)), Logger::Information); - - QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); - emit updated_p(); - return; - } - } - } + void ksl_busyStart() + { + KeyStoreListContext *c = (KeyStoreListContext *)sender(); + + QCA_logTextMessage(QString("keystore: ksl_busyStart %1").arg(c->provider()->name()), Logger::Information); + + if (!busySources.contains(c)) { + busySources += c; + + QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); + emit updated_p(); + } + } + + void ksl_busyEnd() + { + KeyStoreListContext *c = (KeyStoreListContext *)sender(); + + QCA_logTextMessage(QString("keystore: ksl_busyEnd %1").arg(c->provider()->name()), Logger::Information); + + busySources.remove(c); + bool changed = updateStores(c); + bool any_busy = !busySources.isEmpty(); + + if (!any_busy) { + m.lock(); + busy = false; + m.unlock(); + } + + if (!any_busy || changed) { + QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); + emit updated_p(); + } + } + + void ksl_updated() + { + KeyStoreListContext *c = (KeyStoreListContext *)sender(); + + QCA_logTextMessage(QString("keystore: ksl_updated %1").arg(c->provider()->name()), Logger::Information); + + bool changed = updateStores(c); + if (changed) { + QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); + emit updated_p(); + } + } + + void ksl_diagnosticText(const QString &str) + { + QMutexLocker locker(&m); + dtext += str; + dtext = truncate_log(dtext, 100000); + } + + void ksl_storeUpdated(int id) + { + KeyStoreListContext *c = (KeyStoreListContext *)sender(); + + QCA_logTextMessage(QString("keystore: ksl_storeUpdated %1 %2").arg(c->provider()->name(), QString::number(id)), Logger::Information); + + QMutexLocker locker(&m); + for (int n = 0; n < items.count(); ++n) { + Item &i = items[n]; + if (i.owner == c && i.storeContextId == id) { + ++i.updateCount; + + QCA_logTextMessage(QString("keystore: %1 updateCount = %2").arg(i.name, QString::number(i.updateCount)), Logger::Information); + + QCA_logTextMessage(QString("keystore: emitting updated"), Logger::Information); + emit updated_p(); + return; + } + } + } }; KeyStoreTracker *KeyStoreTracker::self = 0; @@ -606,29 +603,29 @@ //---------------------------------------------------------------------------- class KeyStoreThread : public SyncThread { - Q_OBJECT + Q_OBJECT public: - KeyStoreTracker *tracker; - QMutex call_mutex; - - KeyStoreThread(QObject *parent = 0) : SyncThread(parent) - { - } - - ~KeyStoreThread() - { - stop(); - } - - void atStart() - { - tracker = new KeyStoreTracker; - } - - void atEnd() - { - delete tracker; - } + KeyStoreTracker *tracker; + QMutex call_mutex; + + KeyStoreThread(QObject *parent = 0) : SyncThread(parent) + { + } + + ~KeyStoreThread() + { + stop(); + } + + void atStart() + { + tracker = new KeyStoreTracker; + } + + void atEnd() + { + delete tracker; + } }; //---------------------------------------------------------------------------- @@ -642,294 +639,288 @@ class KeyStoreManagerGlobal { public: - KeyStoreThread *thread; - - KeyStoreManagerGlobal() - { - thread = new KeyStoreThread; - thread->moveToThread(QCoreApplication::instance()->thread()); - thread->start(); - } - - ~KeyStoreManagerGlobal() - { - delete thread; - } + KeyStoreThread *thread; + + KeyStoreManagerGlobal() + { + thread = new KeyStoreThread; + thread->moveToThread(QCoreApplication::instance()->thread()); + thread->start(); + } + + ~KeyStoreManagerGlobal() + { + delete thread; + } }; // this function is thread-safe static QVariant trackercall(const char *method, const QVariantList &args = QVariantList()) { - QVariant ret; - bool ok; + QVariant ret; + bool ok; - g_ksm->thread->call_mutex.lock(); - ret = g_ksm->thread->call(KeyStoreTracker::instance(), method, args, &ok); - g_ksm->thread->call_mutex.unlock(); + g_ksm->thread->call_mutex.lock(); + ret = g_ksm->thread->call(KeyStoreTracker::instance(), method, args, &ok); + g_ksm->thread->call_mutex.unlock(); - Q_ASSERT(ok); - if(!ok) - { - fprintf(stderr, "QCA: KeyStoreTracker call [%s] failed.\n", method); - abort(); - return QVariant(); - } - return ret; + Q_ASSERT(ok); + if (!ok) { + fprintf(stderr, "QCA: KeyStoreTracker call [%s] failed.\n", method); + abort(); + return QVariant(); + } + return ret; } //---------------------------------------------------------------------------- // KeyStoreEntry //---------------------------------------------------------------------------- class KeyStoreEntry::Private { public: - bool accessible; + bool accessible; - Private() - { - accessible = false; - } + Private() + { + accessible = false; + } }; KeyStoreEntry::KeyStoreEntry() -:d(new Private) + : d(new Private) { } KeyStoreEntry::KeyStoreEntry(const QString &serialized) -:d(new Private) + : d(new Private) { - *this = fromString(serialized); + *this = fromString(serialized); } KeyStoreEntry::KeyStoreEntry(const KeyStoreEntry &from) -:Algorithm(from), d(new Private(*from.d)) + : Algorithm(from), d(new Private(*from.d)) { } KeyStoreEntry::~KeyStoreEntry() { - delete d; + delete d; } -KeyStoreEntry & KeyStoreEntry::operator=(const KeyStoreEntry &from) +KeyStoreEntry &KeyStoreEntry::operator=(const KeyStoreEntry &from) { - Algorithm::operator=(from); - *d = *from.d; - return *this; + Algorithm::operator=(from); + *d = *from.d; + return *this; } bool KeyStoreEntry::isNull() const { - return (!context() ? true : false); + return (!context() ? true : false); } bool KeyStoreEntry::isAvailable() const { - return static_cast(context())->isAvailable(); + return static_cast(context())->isAvailable(); } bool KeyStoreEntry::isAccessible() const { - return d->accessible; + return d->accessible; } KeyStoreEntry::Type KeyStoreEntry::type() const { - return static_cast(context())->type(); + return static_cast(context())->type(); } QString KeyStoreEntry::name() const { - return static_cast(context())->name(); + return static_cast(context())->name(); } QString KeyStoreEntry::id() const { - return static_cast(context())->id(); + return static_cast(context())->id(); } QString KeyStoreEntry::storeName() const { - return static_cast(context())->storeName(); + return static_cast(context())->storeName(); } QString KeyStoreEntry::storeId() const { - return static_cast(context())->storeId(); + return static_cast(context())->storeId(); } QString KeyStoreEntry::toString() const { - return static_cast(context())->serialize(); + return static_cast(context())->serialize(); } KeyStoreEntry KeyStoreEntry::fromString(const QString &serialized) { - KeyStoreEntry e; - KeyStoreEntryContext *c = (KeyStoreEntryContext *)KeyStoreTracker::instance()->entryPassive(serialized); - if(c) - e.change(c); - return e; + KeyStoreEntry e; + KeyStoreEntryContext *c = (KeyStoreEntryContext *)KeyStoreTracker::instance()->entryPassive(serialized); + if (c) { + e.change(c); + } + return e; } KeyBundle KeyStoreEntry::keyBundle() const { - return static_cast(context())->keyBundle(); + return static_cast(context())->keyBundle(); } Certificate KeyStoreEntry::certificate() const { - return static_cast(context())->certificate(); + return static_cast(context())->certificate(); } CRL KeyStoreEntry::crl() const { - return static_cast(context())->crl(); + return static_cast(context())->crl(); } PGPKey KeyStoreEntry::pgpSecretKey() const { - return static_cast(context())->pgpSecretKey(); + return static_cast(context())->pgpSecretKey(); } PGPKey KeyStoreEntry::pgpPublicKey() const { - return static_cast(context())->pgpPublicKey(); + return static_cast(context())->pgpPublicKey(); } bool KeyStoreEntry::ensureAvailable() { - QString storeId = this->storeId(); - QString entryId = id(); + QString storeId = this->storeId(); + QString entryId = id(); #if QT_VERSION >= 0x050000 - KeyStoreEntryContext *c = (KeyStoreEntryContext *)trackercall("entry", QVariantList() << storeId << entryId).value(); + KeyStoreEntryContext *c = (KeyStoreEntryContext *)trackercall("entry", QVariantList() << storeId << entryId).value(); #else - KeyStoreEntryContext *c = (KeyStoreEntryContext *)qVariantValue(trackercall("entry", QVariantList() << storeId << entryId)); + KeyStoreEntryContext *c = (KeyStoreEntryContext *)qVariantValue(trackercall("entry", QVariantList() << storeId << entryId)); #endif - if(c) - change(c); - return isAvailable(); + if (c) { + change(c); + } + return isAvailable(); } bool KeyStoreEntry::ensureAccess() { - if(!ensureAvailable()) - { - d->accessible = false; - return false; - } - bool ok = static_cast(context())->ensureAccess(); - d->accessible = ok; - return d->accessible; + if (!ensureAvailable()) { + d->accessible = false; + return false; + } + bool ok = static_cast(context())->ensureAccess(); + d->accessible = ok; + return d->accessible; } //---------------------------------------------------------------------------- // KeyStoreEntryWatcher //---------------------------------------------------------------------------- class KeyStoreEntryWatcher::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - KeyStoreEntryWatcher *q; - KeyStoreManager ksm; - KeyStoreEntry entry; - QString storeId, entryId; - KeyStore *ks; - bool avail; - - Private(KeyStoreEntryWatcher *_q) : QObject(_q), q(_q), ksm(this) - { - ks = 0; - avail = false; - connect(&ksm, SIGNAL(keyStoreAvailable(const QString &)), SLOT(ksm_available(const QString &))); - } - - ~Private() - { - delete ks; - } - - void start() - { - QStringList list = ksm.keyStores(); - foreach(const QString &storeId, list) - ksm_available(storeId); - } + KeyStoreEntryWatcher *q; + KeyStoreManager ksm; + KeyStoreEntry entry; + QString storeId, entryId; + KeyStore *ks; + bool avail; + + Private(KeyStoreEntryWatcher *_q) : QObject(_q), q(_q), ksm(this) + { + ks = 0; + avail = false; + connect(&ksm, SIGNAL(keyStoreAvailable(QString)), SLOT(ksm_available(QString))); + } + + ~Private() + { + delete ks; + } + + void start() + { + QStringList list = ksm.keyStores(); + foreach (const QString &storeId, list) { + ksm_available(storeId); + } + } private slots: - void ksm_available(const QString &_storeId) - { - // we only care about one store - if(_storeId == storeId) - { - ks = new KeyStore(storeId, &ksm); - connect(ks, SIGNAL(updated()), SLOT(ks_updated())); - ks->startAsynchronousMode(); - } - } - - void ks_updated() - { - bool found = false; - QList list = ks->entryList(); - foreach(const KeyStoreEntry &e, list) - { - if(e.id() == entryId && e.isAvailable()) - { - found = true; - if(!avail) - entry = e; - break; - } - } - - if(found && !avail) - { - avail = true; - emit q->available(); - } - else if(!found && avail) - { - avail = false; - emit q->unavailable(); - } - } - - void ks_unavailable() - { - delete ks; - ks = 0; - - if(avail) - { - avail = false; - emit q->unavailable(); - } - } + void ksm_available(const QString &_storeId) + { + // we only care about one store + if (_storeId == storeId) { + ks = new KeyStore(storeId, &ksm); + connect(ks, SIGNAL(updated()), SLOT(ks_updated())); + ks->startAsynchronousMode(); + } + } + + void ks_updated() + { + bool found = false; + QList list = ks->entryList(); + foreach (const KeyStoreEntry &e, list) { + if (e.id() == entryId && e.isAvailable()) { + found = true; + if (!avail) { + entry = e; + } + break; + } + } + + if (found && !avail) { + avail = true; + emit q->available(); + } else if (!found && avail) { + avail = false; + emit q->unavailable(); + } + } + + void ks_unavailable() + { + delete ks; + ks = 0; + + if (avail) { + avail = false; + emit q->unavailable(); + } + } }; KeyStoreEntryWatcher::KeyStoreEntryWatcher(const KeyStoreEntry &e, QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); - if(!e.isNull()) - { - d->entry = e; - d->storeId = e.storeId(); - d->entryId = e.id(); - d->start(); - } + d = new Private(this); + if (!e.isNull()) { + d->entry = e; + d->storeId = e.storeId(); + d->entryId = e.id(); + d->start(); + } } KeyStoreEntryWatcher::~KeyStoreEntryWatcher() { - delete d; + delete d; } KeyStoreEntry KeyStoreEntryWatcher::entry() const { - return d->entry; + return d->entry; } //---------------------------------------------------------------------------- @@ -939,833 +930,812 @@ class KeyStoreWriteEntry { public: - enum Type { TypeKeyBundle, TypeCertificate, TypeCRL, TypePGPKey }; - - Type type; - KeyBundle keyBundle; - Certificate cert; - CRL crl; - PGPKey pgpKey; - - KeyStoreWriteEntry() - { - } - - KeyStoreWriteEntry(const KeyBundle &_keyBundle) - :type(TypeKeyBundle), keyBundle(_keyBundle) - { - } - - KeyStoreWriteEntry(const Certificate &_cert) - :type(TypeCertificate), cert(_cert) - { - } - - KeyStoreWriteEntry(const CRL &_crl) - :type(TypeCRL), crl(_crl) - { - } - - KeyStoreWriteEntry(const PGPKey &_pgpKey) - :type(TypePGPKey), pgpKey(_pgpKey) - { - } + enum Type { TypeKeyBundle, TypeCertificate, TypeCRL, TypePGPKey }; + + Type type; + KeyBundle keyBundle; + Certificate cert; + CRL crl; + PGPKey pgpKey; + + KeyStoreWriteEntry() + { + } + + KeyStoreWriteEntry(const KeyBundle &_keyBundle) + : type(TypeKeyBundle), keyBundle(_keyBundle) + { + } + + KeyStoreWriteEntry(const Certificate &_cert) + : type(TypeCertificate), cert(_cert) + { + } + + KeyStoreWriteEntry(const CRL &_crl) + : type(TypeCRL), crl(_crl) + { + } + + KeyStoreWriteEntry(const PGPKey &_pgpKey) + : type(TypePGPKey), pgpKey(_pgpKey) + { + } }; class KeyStoreOperation : public QThread { - Q_OBJECT + Q_OBJECT public: - enum Type { EntryList, WriteEntry, RemoveEntry }; + enum Type { EntryList, WriteEntry, RemoveEntry }; - Type type; - int trackerId; + Type type; + int trackerId; - KeyStoreWriteEntry wentry; // in: WriteEntry - QList entryList; // out: EntryList - QString entryId; // in: RemoveEntry, out: WriteEntry - bool success; // out: RemoveEntry + KeyStoreWriteEntry wentry; // in: WriteEntry + QList entryList; // out: EntryList + QString entryId; // in: RemoveEntry, out: WriteEntry + bool success; // out: RemoveEntry - KeyStoreOperation(QObject *parent = 0) - :QThread(parent) - { - } + KeyStoreOperation(QObject *parent = 0) + : QThread(parent) + { + } - ~KeyStoreOperation() - { - wait(); - } + ~KeyStoreOperation() + { + wait(); + } protected: - virtual void run() - { - if(type == EntryList) + virtual void run() + { + if (type == EntryList) #if QT_VERSION >= 0x050000 - entryList = trackercall("entryList", QVariantList() << trackerId).value< QList >(); + entryList = trackercall("entryList", QVariantList() << trackerId).value< QList >(); #else - entryList = qVariantValue< QList >(trackercall("entryList", QVariantList() << trackerId)); + entryList = qVariantValue< QList >(trackercall("entryList", QVariantList() << trackerId)); #endif - else if(type == WriteEntry) - { - QVariant arg; + else if (type == WriteEntry) { + QVariant arg; #if QT_VERSION >= 0x050000 - if(wentry.type == KeyStoreWriteEntry::TypeKeyBundle) - arg.setValue(wentry.keyBundle); - else if(wentry.type == KeyStoreWriteEntry::TypeCertificate) - arg.setValue(wentry.cert); - else if(wentry.type == KeyStoreWriteEntry::TypeCRL) - arg.setValue(wentry.crl); - else if(wentry.type == KeyStoreWriteEntry::TypePGPKey) - arg.setValue(wentry.pgpKey); + if (wentry.type == KeyStoreWriteEntry::TypeKeyBundle) { + arg.setValue(wentry.keyBundle); + } else if (wentry.type == KeyStoreWriteEntry::TypeCertificate) { + arg.setValue(wentry.cert); + } else if (wentry.type == KeyStoreWriteEntry::TypeCRL) { + arg.setValue(wentry.crl); + } else if (wentry.type == KeyStoreWriteEntry::TypePGPKey) { + arg.setValue(wentry.pgpKey); + } #else - if(wentry.type == KeyStoreWriteEntry::TypeKeyBundle) - qVariantSetValue(arg, wentry.keyBundle); - else if(wentry.type == KeyStoreWriteEntry::TypeCertificate) - qVariantSetValue(arg, wentry.cert); - else if(wentry.type == KeyStoreWriteEntry::TypeCRL) - qVariantSetValue(arg, wentry.crl); - else if(wentry.type == KeyStoreWriteEntry::TypePGPKey) - qVariantSetValue(arg, wentry.pgpKey); + if (wentry.type == KeyStoreWriteEntry::TypeKeyBundle) { + qVariantSetValue(arg, wentry.keyBundle); + } else if (wentry.type == KeyStoreWriteEntry::TypeCertificate) { + qVariantSetValue(arg, wentry.cert); + } else if (wentry.type == KeyStoreWriteEntry::TypeCRL) { + qVariantSetValue(arg, wentry.crl); + } else if (wentry.type == KeyStoreWriteEntry::TypePGPKey) { + qVariantSetValue(arg, wentry.pgpKey); + } #endif - // note: each variant in the argument list is resolved - // to its native type. so even though it looks like - // we're attempting to call a method named - // writeEntry(QString,QVariant), we're actually - // calling one of many possible methods, such as - // writeEntry(QString,PGPKey) or - // writeEntry(QString,Certificate), etc, depending - // on the type of object we put in the variant. - entryId = trackercall("writeEntry", QVariantList() << trackerId << arg).toString(); - } - else // RemoveEntry - { - success = trackercall("removeEntry", QVariantList() << trackerId << entryId).toBool(); - } - } + // note: each variant in the argument list is resolved + // to its native type. so even though it looks like + // we're attempting to call a method named + // writeEntry(QString,QVariant), we're actually + // calling one of many possible methods, such as + // writeEntry(QString,PGPKey) or + // writeEntry(QString,Certificate), etc, depending + // on the type of object we put in the variant. + entryId = trackercall("writeEntry", QVariantList() << trackerId << arg).toString(); + } else { // RemoveEntry + success = trackercall("removeEntry", QVariantList() << trackerId << entryId).toBool(); + } + } }; class KeyStorePrivate : public QObject { - Q_OBJECT + Q_OBJECT public: - KeyStore *q; - KeyStoreManager *ksm; - int trackerId; - KeyStoreTracker::Item item; - bool async; - bool need_update; - QList latestEntryList; - QList ops; - - KeyStorePrivate(KeyStore *_q) : QObject(_q), q(_q), async(false) - { - } - - ~KeyStorePrivate() - { - qDeleteAll(ops); - } - - // implemented below, after KeyStorePrivate is declared - void reg(); - void unreg(); - KeyStoreTracker::Item *getItem(const QString &storeId); - KeyStoreTracker::Item *getItem(int trackerId); - - void invalidate() - { - trackerId = -1; - unreg(); - } - - bool have_entryList_op() const - { - foreach(KeyStoreOperation *op, ops) - { - if(op->type == KeyStoreOperation::EntryList) - return true; - } - return false; - } - - void handle_updated() - { - if(async) - { - if(!have_entryList_op()) - async_entryList(); - else - need_update = true; - } - else - emit q->updated(); - } - - void async_entryList() - { - KeyStoreOperation *op = new KeyStoreOperation(this); - // use queued for signal-safety - connect(op, SIGNAL(finished()), SLOT(op_finished()), Qt::QueuedConnection); - op->type = KeyStoreOperation::EntryList; - op->trackerId = trackerId; - ops += op; - op->start(); - } - - void async_writeEntry(const KeyStoreWriteEntry &wentry) - { - KeyStoreOperation *op = new KeyStoreOperation(this); - // use queued for signal-safety - connect(op, SIGNAL(finished()), SLOT(op_finished()), Qt::QueuedConnection); - op->type = KeyStoreOperation::WriteEntry; - op->trackerId = trackerId; - op->wentry = wentry; - ops += op; - op->start(); - } - - void async_removeEntry(const QString &entryId) - { - KeyStoreOperation *op = new KeyStoreOperation(this); - // use queued for signal-safety - connect(op, SIGNAL(finished()), SLOT(op_finished()), Qt::QueuedConnection); - op->type = KeyStoreOperation::RemoveEntry; - op->trackerId = trackerId; - op->entryId = entryId; - ops += op; - op->start(); - } + KeyStore *q; + KeyStoreManager *ksm; + int trackerId; + KeyStoreTracker::Item item; + bool async; + bool need_update; + QList latestEntryList; + QList ops; + + KeyStorePrivate(KeyStore *_q) : QObject(_q), q(_q), async(false) + { + } + + ~KeyStorePrivate() + { + qDeleteAll(ops); + } + + // implemented below, after KeyStorePrivate is declared + void reg(); + void unreg(); + KeyStoreTracker::Item *getItem(const QString &storeId); + KeyStoreTracker::Item *getItem(int trackerId); + + void invalidate() + { + trackerId = -1; + unreg(); + } + + bool have_entryList_op() const + { + foreach (KeyStoreOperation *op, ops) { + if (op->type == KeyStoreOperation::EntryList) { + return true; + } + } + return false; + } + + void handle_updated() + { + if (async) { + if (!have_entryList_op()) { + async_entryList(); + } else { + need_update = true; + } + } else { + emit q->updated(); + } + } + + void async_entryList() + { + KeyStoreOperation *op = new KeyStoreOperation(this); + // use queued for signal-safety + connect(op, SIGNAL(finished()), SLOT(op_finished()), Qt::QueuedConnection); + op->type = KeyStoreOperation::EntryList; + op->trackerId = trackerId; + ops += op; + op->start(); + } + + void async_writeEntry(const KeyStoreWriteEntry &wentry) + { + KeyStoreOperation *op = new KeyStoreOperation(this); + // use queued for signal-safety + connect(op, SIGNAL(finished()), SLOT(op_finished()), Qt::QueuedConnection); + op->type = KeyStoreOperation::WriteEntry; + op->trackerId = trackerId; + op->wentry = wentry; + ops += op; + op->start(); + } + + void async_removeEntry(const QString &entryId) + { + KeyStoreOperation *op = new KeyStoreOperation(this); + // use queued for signal-safety + connect(op, SIGNAL(finished()), SLOT(op_finished()), Qt::QueuedConnection); + op->type = KeyStoreOperation::RemoveEntry; + op->trackerId = trackerId; + op->entryId = entryId; + ops += op; + op->start(); + } private slots: - void op_finished() - { - KeyStoreOperation *op = (KeyStoreOperation *)sender(); - - if(op->type == KeyStoreOperation::EntryList) - { - latestEntryList = op->entryList; - ops.removeAll(op); - delete op; - - if(need_update) - { - need_update = false; - async_entryList(); - } - - emit q->updated(); - } - else if(op->type == KeyStoreOperation::WriteEntry) - { - QString entryId = op->entryId; - ops.removeAll(op); - delete op; - - emit q->entryWritten(entryId); - } - else // RemoveEntry - { - bool success = op->success; - ops.removeAll(op); - delete op; - - emit q->entryRemoved(success); - } - } + void op_finished() + { + KeyStoreOperation *op = (KeyStoreOperation *)sender(); + + if (op->type == KeyStoreOperation::EntryList) { + latestEntryList = op->entryList; + ops.removeAll(op); + delete op; + + if (need_update) { + need_update = false; + async_entryList(); + } + + emit q->updated(); + } else if (op->type == KeyStoreOperation::WriteEntry) { + QString entryId = op->entryId; + ops.removeAll(op); + delete op; + + emit q->entryWritten(entryId); + } else { // RemoveEntry + bool success = op->success; + ops.removeAll(op); + delete op; + + emit q->entryRemoved(success); + } + } }; KeyStore::KeyStore(const QString &id, KeyStoreManager *keyStoreManager) -:QObject(keyStoreManager) + : QObject(keyStoreManager) { - d = new KeyStorePrivate(this); - d->ksm = keyStoreManager; + d = new KeyStorePrivate(this); + d->ksm = keyStoreManager; - KeyStoreTracker::Item *i = d->getItem(id); - if(i) - { - d->trackerId = i->trackerId; - d->item = *i; - d->reg(); - } - else - d->trackerId = -1; + KeyStoreTracker::Item *i = d->getItem(id); + if (i) { + d->trackerId = i->trackerId; + d->item = *i; + d->reg(); + } else { + d->trackerId = -1; + } } KeyStore::~KeyStore() { - if(d->trackerId != -1) - d->unreg(); - delete d; + if (d->trackerId != -1) { + d->unreg(); + } + delete d; } bool KeyStore::isValid() const { - return (d->getItem(d->trackerId) ? true : false); + return (d->getItem(d->trackerId) ? true : false); } KeyStore::Type KeyStore::type() const { - return d->item.type; + return d->item.type; } QString KeyStore::name() const { - return d->item.name; + return d->item.name; } QString KeyStore::id() const { - return d->item.storeId; + return d->item.storeId; } bool KeyStore::isReadOnly() const { - return d->item.isReadOnly; + return d->item.isReadOnly; } void KeyStore::startAsynchronousMode() { - if(d->async) - return; + if (d->async) { + return; + } - d->async = true; + d->async = true; - // initial entrylist - d->need_update = false; - d->async_entryList(); + // initial entrylist + d->need_update = false; + d->async_entryList(); } QList KeyStore::entryList() const { - if(d->async) - return d->latestEntryList; + if (d->async) { + return d->latestEntryList; + } - if(d->trackerId == -1) - return QList(); + if (d->trackerId == -1) { + return QList(); + } #if QT_VERSION >= 0x050000 - return trackercall("entryList", QVariantList() << d->trackerId).value< QList >(); + return trackercall("entryList", QVariantList() << d->trackerId).value< QList >(); #else - return qVariantValue< QList >(trackercall("entryList", QVariantList() << d->trackerId)); + return qVariantValue< QList >(trackercall("entryList", QVariantList() << d->trackerId)); #endif } bool KeyStore::holdsTrustedCertificates() const { - QList list; - if(d->trackerId == -1) - return false; + QList list; + if (d->trackerId == -1) { + return false; + } #if QT_VERSION >= 0x050000 - list = trackercall("entryTypes", QVariantList() << d->trackerId).value< QList >(); + list = trackercall("entryTypes", QVariantList() << d->trackerId).value< QList >(); #else - list = qVariantValue< QList >(trackercall("entryTypes", QVariantList() << d->trackerId)); + list = qVariantValue< QList >(trackercall("entryTypes", QVariantList() << d->trackerId)); #endif - if(list.contains(KeyStoreEntry::TypeCertificate) || list.contains(KeyStoreEntry::TypeCRL)) - return true; - return false; + if (list.contains(KeyStoreEntry::TypeCertificate) || list.contains(KeyStoreEntry::TypeCRL)) { + return true; + } + return false; } bool KeyStore::holdsIdentities() const { - QList list; - if(d->trackerId == -1) - return false; + QList list; + if (d->trackerId == -1) { + return false; + } #if QT_VERSION >= 0x050000 - list = trackercall("entryTypes", QVariantList() << d->trackerId).value< QList >(); + list = trackercall("entryTypes", QVariantList() << d->trackerId).value< QList >(); #else - list = qVariantValue< QList >(trackercall("entryTypes", QVariantList() << d->trackerId)); + list = qVariantValue< QList >(trackercall("entryTypes", QVariantList() << d->trackerId)); #endif - if(list.contains(KeyStoreEntry::TypeKeyBundle) || list.contains(KeyStoreEntry::TypePGPSecretKey)) - return true; - return false; + if (list.contains(KeyStoreEntry::TypeKeyBundle) || list.contains(KeyStoreEntry::TypePGPSecretKey)) { + return true; + } + return false; } bool KeyStore::holdsPGPPublicKeys() const { - QList list; - if(d->trackerId == -1) - return false; + QList list; + if (d->trackerId == -1) { + return false; + } #if QT_VERSION >= 0x050000 - list = trackercall("entryTypes", QVariantList() << d->trackerId).value< QList >(); + list = trackercall("entryTypes", QVariantList() << d->trackerId).value< QList >(); #else - list = qVariantValue< QList >(trackercall("entryTypes", QVariantList() << d->trackerId)); + list = qVariantValue< QList >(trackercall("entryTypes", QVariantList() << d->trackerId)); #endif - if(list.contains(KeyStoreEntry::TypePGPPublicKey)) - return true; - return false; + if (list.contains(KeyStoreEntry::TypePGPPublicKey)) { + return true; + } + return false; } QString KeyStore::writeEntry(const KeyBundle &kb) { - if(d->async) - { - d->async_writeEntry(KeyStoreWriteEntry(kb)); - return QString(); - } - else - { - QVariant arg; - qVariantSetValue(arg, kb); - return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); - } + if (d->async) { + d->async_writeEntry(KeyStoreWriteEntry(kb)); + return QString(); + } else { + QVariant arg; + qVariantSetValue(arg, kb); + return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); + } } QString KeyStore::writeEntry(const Certificate &cert) { - if(d->async) - { - d->async_writeEntry(KeyStoreWriteEntry(cert)); - return QString(); - } - else - { - QVariant arg; - qVariantSetValue(arg, cert); - return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); - } + if (d->async) { + d->async_writeEntry(KeyStoreWriteEntry(cert)); + return QString(); + } else { + QVariant arg; + qVariantSetValue(arg, cert); + return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); + } } QString KeyStore::writeEntry(const CRL &crl) { - if(d->async) - { - d->async_writeEntry(KeyStoreWriteEntry(crl)); - return QString(); - } - else - { - QVariant arg; - qVariantSetValue(arg, crl); - return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); - } + if (d->async) { + d->async_writeEntry(KeyStoreWriteEntry(crl)); + return QString(); + } else { + QVariant arg; + qVariantSetValue(arg, crl); + return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); + } } QString KeyStore::writeEntry(const PGPKey &key) { - if(d->async) - { - d->async_writeEntry(KeyStoreWriteEntry(key)); - return QString(); - } - else - { - QVariant arg; - qVariantSetValue(arg, key); - return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); - } + if (d->async) { + d->async_writeEntry(KeyStoreWriteEntry(key)); + return QString(); + } else { + QVariant arg; + qVariantSetValue(arg, key); + return trackercall("writeEntry", QVariantList() << d->trackerId << arg).toString(); + } } bool KeyStore::removeEntry(const QString &id) { - if(d->async) - { - d->async_removeEntry(id); - return false; - } - else - { - return trackercall("removeEntry", QVariantList() << d->trackerId << id).toBool(); - } + if (d->async) { + d->async_removeEntry(id); + return false; + } else { + return trackercall("removeEntry", QVariantList() << d->trackerId << id).toBool(); + } } //---------------------------------------------------------------------------- // KeyStoreManager //---------------------------------------------------------------------------- static void ensure_init() { - QMutexLocker locker(ksm_mutex()); - if(!g_ksm) - g_ksm = new KeyStoreManagerGlobal; + QMutexLocker locker(ksm_mutex()); + if (!g_ksm) { + g_ksm = new KeyStoreManagerGlobal; + } } // static functions void KeyStoreManager::start() { - ensure_init(); - QMetaObject::invokeMethod(KeyStoreTracker::instance(), "start", Qt::QueuedConnection); - trackercall("spinEventLoop"); + ensure_init(); + QMetaObject::invokeMethod(KeyStoreTracker::instance(), "start", Qt::QueuedConnection); + trackercall("spinEventLoop"); } void KeyStoreManager::start(const QString &provider) { - ensure_init(); - QMetaObject::invokeMethod(KeyStoreTracker::instance(), "start", Qt::QueuedConnection, Q_ARG(QString, provider)); - trackercall("spinEventLoop"); + ensure_init(); + QMetaObject::invokeMethod(KeyStoreTracker::instance(), "start", Qt::QueuedConnection, Q_ARG(QString, provider)); + trackercall("spinEventLoop"); } QString KeyStoreManager::diagnosticText() { - ensure_init(); + ensure_init(); - // spin one event cycle in the tracker, to receive any pending text. - // note that since trackercall also goes through the eventloop, - // this may end up doing two rounds. probably no big deal. - trackercall("spinEventLoop"); + // spin one event cycle in the tracker, to receive any pending text. + // note that since trackercall also goes through the eventloop, + // this may end up doing two rounds. probably no big deal. + trackercall("spinEventLoop"); - return KeyStoreTracker::instance()->getDText(); + return KeyStoreTracker::instance()->getDText(); } void KeyStoreManager::clearDiagnosticText() { - ensure_init(); - KeyStoreTracker::instance()->clearDText(); + ensure_init(); + KeyStoreTracker::instance()->clearDText(); } void KeyStoreManager::scan() { - ensure_init(); - QMetaObject::invokeMethod(KeyStoreTracker::instance(), "scan", Qt::QueuedConnection); + ensure_init(); + QMetaObject::invokeMethod(KeyStoreTracker::instance(), "scan", Qt::QueuedConnection); } void KeyStoreManager::shutdown() { - QMutexLocker locker(ksm_mutex()); - delete g_ksm; - g_ksm = 0; + QMutexLocker locker(ksm_mutex()); + delete g_ksm; + g_ksm = 0; } // object class KeyStoreManagerPrivate : public QObject { - Q_OBJECT + Q_OBJECT public: - KeyStoreManager *q; - - QMutex m; - QWaitCondition w; - bool busy; - QList items; - bool pending, waiting; - - QMultiHash keyStoreForTrackerId; - QHash trackerIdForKeyStore; - - KeyStoreManagerPrivate(KeyStoreManager *_q) : QObject(_q), q(_q) - { - pending = false; - waiting = false; - } - - ~KeyStoreManagerPrivate() - { - // invalidate registered keystores - QList list; - QHashIterator it(trackerIdForKeyStore); - while(it.hasNext()) - { - it.next(); - list += it.key(); - } - foreach(KeyStore *ks, list) - ks->d->invalidate(); - } - - // for keystore - void reg(KeyStore *ks, int trackerId) - { - keyStoreForTrackerId.insert(trackerId, ks); - trackerIdForKeyStore.insert(ks, trackerId); - } - - void unreg(KeyStore *ks) - { - int trackerId = trackerIdForKeyStore.take(ks); - - // this is the only way I know to remove one item from a multihash - QList vals = keyStoreForTrackerId.values(trackerId); - keyStoreForTrackerId.remove(trackerId); - vals.removeAll(ks); - foreach(KeyStore *i, vals) - keyStoreForTrackerId.insert(trackerId, i); - } - - KeyStoreTracker::Item *getItem(const QString &storeId) - { - for(int n = 0; n < items.count(); ++n) - { - KeyStoreTracker::Item *i = &items[n]; - if(i->storeId == storeId) - return i; - } - return 0; - } - - KeyStoreTracker::Item *getItem(int trackerId) - { - for(int n = 0; n < items.count(); ++n) - { - KeyStoreTracker::Item *i = &items[n]; - if(i->trackerId == trackerId) - return i; - } - return 0; - } - - void do_update() - { - // ksm doesn't have reset or state changes so we can - // use QPointer here for full SS. - QPointer self(this); - - bool newbusy = KeyStoreTracker::instance()->isBusy(); - QList newitems = KeyStoreTracker::instance()->getItems(); - - if(!busy && newbusy) - { - emit q->busyStarted(); - if(!self) - return; - } - if(busy && !newbusy) - { - emit q->busyFinished(); - if(!self) - return; - } - - QStringList here; - QList changed; - QList gone; - - // removed - for(int n = 0; n < items.count(); ++n) - { - KeyStoreTracker::Item &i = items[n]; - bool found = false; - for(int k = 0; k < newitems.count(); ++k) - { - if(i.trackerId == newitems[k].trackerId) - { - found = true; - break; - } - } - if(!found) - gone += i.trackerId; - } - - // changed - for(int n = 0; n < items.count(); ++n) - { - KeyStoreTracker::Item &i = items[n]; - for(int k = 0; k < newitems.count(); ++k) - { - if(i.trackerId == newitems[k].trackerId) - { - if(i.updateCount < newitems[k].updateCount) - changed += i.trackerId; - break; - } - } - } - - // added - for(int n = 0; n < newitems.count(); ++n) - { - KeyStoreTracker::Item &i = newitems[n]; - bool found = false; - for(int k = 0; k < items.count(); ++k) - { - if(i.trackerId == items[k].trackerId) - { - found = true; - break; - } - } - if(!found) - here += i.storeId; - } - - busy = newbusy; - items = newitems; - - // signals - foreach(int trackerId, gone) - { - KeyStore *ks = keyStoreForTrackerId.value(trackerId); - if(ks) - { - ks->d->invalidate(); - emit ks->unavailable(); - if(!self) - return; - } - } - - foreach(int trackerId, changed) - { - KeyStore *ks = keyStoreForTrackerId.value(trackerId); - if(ks) - { - ks->d->handle_updated(); - if(!self) - return; - } - } - - foreach(const QString &storeId, here) - { - emit q->keyStoreAvailable(storeId); - if(!self) - return; - } - } + KeyStoreManager *q; + + QMutex m; + QWaitCondition w; + bool busy; + QList items; + bool pending, waiting; + + QMultiHash keyStoreForTrackerId; + QHash trackerIdForKeyStore; + + KeyStoreManagerPrivate(KeyStoreManager *_q) : QObject(_q), q(_q) + { + pending = false; + waiting = false; + } + + ~KeyStoreManagerPrivate() + { + // invalidate registered keystores + QList list; + QHashIterator it(trackerIdForKeyStore); + while (it.hasNext()) { + it.next(); + list += it.key(); + } + foreach (KeyStore *ks, list) { + ks->d->invalidate(); + } + } + + // for keystore + void reg(KeyStore *ks, int trackerId) + { + keyStoreForTrackerId.insert(trackerId, ks); + trackerIdForKeyStore.insert(ks, trackerId); + } + + void unreg(KeyStore *ks) + { + int trackerId = trackerIdForKeyStore.take(ks); + + // this is the only way I know to remove one item from a multihash + QList vals = keyStoreForTrackerId.values(trackerId); + keyStoreForTrackerId.remove(trackerId); + vals.removeAll(ks); + foreach (KeyStore *i, vals) { + keyStoreForTrackerId.insert(trackerId, i); + } + } + + KeyStoreTracker::Item *getItem(const QString &storeId) + { + for (int n = 0; n < items.count(); ++n) { + KeyStoreTracker::Item *i = &items[n]; + if (i->storeId == storeId) { + return i; + } + } + return 0; + } + + KeyStoreTracker::Item *getItem(int trackerId) + { + for (int n = 0; n < items.count(); ++n) { + KeyStoreTracker::Item *i = &items[n]; + if (i->trackerId == trackerId) { + return i; + } + } + return 0; + } + + void do_update() + { + // ksm doesn't have reset or state changes so we can + // use QPointer here for full SS. + QPointer self(this); + + bool newbusy = KeyStoreTracker::instance()->isBusy(); + QList newitems = KeyStoreTracker::instance()->getItems(); + + if (!busy && newbusy) { + emit q->busyStarted(); + if (!self) { + return; + } + } + if (busy && !newbusy) { + emit q->busyFinished(); + if (!self) { + return; + } + } + + QStringList here; + QList changed; + QList gone; + + // removed + for (int n = 0; n < items.count(); ++n) { + KeyStoreTracker::Item &i = items[n]; + bool found = false; + for (int k = 0; k < newitems.count(); ++k) { + if (i.trackerId == newitems[k].trackerId) { + found = true; + break; + } + } + if (!found) { + gone += i.trackerId; + } + } + + // changed + for (int n = 0; n < items.count(); ++n) { + KeyStoreTracker::Item &i = items[n]; + for (int k = 0; k < newitems.count(); ++k) { + if (i.trackerId == newitems[k].trackerId) { + if (i.updateCount < newitems[k].updateCount) { + changed += i.trackerId; + } + break; + } + } + } + + // added + for (int n = 0; n < newitems.count(); ++n) { + KeyStoreTracker::Item &i = newitems[n]; + bool found = false; + for (int k = 0; k < items.count(); ++k) { + if (i.trackerId == items[k].trackerId) { + found = true; + break; + } + } + if (!found) { + here += i.storeId; + } + } + + busy = newbusy; + items = newitems; + + // signals + foreach (int trackerId, gone) { + KeyStore *ks = keyStoreForTrackerId.value(trackerId); + if (ks) { + ks->d->invalidate(); + emit ks->unavailable(); + if (!self) { + return; + } + } + } + + foreach (int trackerId, changed) { + KeyStore *ks = keyStoreForTrackerId.value(trackerId); + if (ks) { + ks->d->handle_updated(); + if (!self) { + return; + } + } + } + + foreach (const QString &storeId, here) { + emit q->keyStoreAvailable(storeId); + if (!self) { + return; + } + } + } public slots: - void tracker_updated() - { - QCA_logTextMessage(QString().sprintf("keystore: %p: tracker_updated start", q), Logger::Information); - - QMutexLocker locker(&m); - if(!pending) - { - QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection); - pending = true; - } - if(waiting && !KeyStoreTracker::instance()->isBusy()) - { - busy = false; - items = KeyStoreTracker::instance()->getItems(); - w.wakeOne(); - } - - QCA_logTextMessage(QString().sprintf("keystore: %p: tracker_updated end", q), Logger::Information); - } - - void update() - { - m.lock(); - pending = false; - m.unlock(); - - do_update(); - } + void tracker_updated() + { + QCA_logTextMessage(QString().sprintf("keystore: %p: tracker_updated start", q), Logger::Information); + + QMutexLocker locker(&m); + if (!pending) { + QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection); + pending = true; + } + if (waiting && !KeyStoreTracker::instance()->isBusy()) { + busy = false; + items = KeyStoreTracker::instance()->getItems(); + w.wakeOne(); + } + + QCA_logTextMessage(QString().sprintf("keystore: %p: tracker_updated end", q), Logger::Information); + } + + void update() + { + m.lock(); + pending = false; + m.unlock(); + + do_update(); + } }; // from KeyStorePrivate void KeyStorePrivate::reg() { - ksm->d->reg(q, trackerId); + ksm->d->reg(q, trackerId); } void KeyStorePrivate::unreg() { - ksm->d->unreg(q); + ksm->d->unreg(q); } KeyStoreTracker::Item *KeyStorePrivate::getItem(const QString &storeId) { - return ksm->d->getItem(storeId); + return ksm->d->getItem(storeId); } KeyStoreTracker::Item *KeyStorePrivate::getItem(int trackerId) { - return ksm->d->getItem(trackerId); + return ksm->d->getItem(trackerId); } KeyStoreManager::KeyStoreManager(QObject *parent) -:QObject(parent) + : QObject(parent) { - ensure_init(); - d = new KeyStoreManagerPrivate(this); - KeyStoreTracker::instance()->addTarget(d); - sync(); + ensure_init(); + d = new KeyStoreManagerPrivate(this); + KeyStoreTracker::instance()->addTarget(d); + sync(); } KeyStoreManager::~KeyStoreManager() { - Q_ASSERT(KeyStoreTracker::instance()); - KeyStoreTracker::instance()->removeTarget(d); - delete d; + Q_ASSERT(KeyStoreTracker::instance()); + KeyStoreTracker::instance()->removeTarget(d); + delete d; } bool KeyStoreManager::isBusy() const { - return d->busy; + return d->busy; } void KeyStoreManager::waitForBusyFinished() { - d->m.lock(); - d->busy = KeyStoreTracker::instance()->isBusy(); - if(d->busy) - { - d->waiting = true; - d->w.wait(&d->m); - d->waiting = false; - } - d->m.unlock(); + d->m.lock(); + d->busy = KeyStoreTracker::instance()->isBusy(); + if (d->busy) { + d->waiting = true; + d->w.wait(&d->m); + d->waiting = false; + } + d->m.unlock(); } QStringList KeyStoreManager::keyStores() const { - QStringList out; - for(int n = 0; n < d->items.count(); ++n) - out += d->items[n].storeId; - return out; + QStringList out; + for (int n = 0; n < d->items.count(); ++n) { + out += d->items[n].storeId; + } + return out; } void KeyStoreManager::sync() { - d->busy = KeyStoreTracker::instance()->isBusy(); - d->items = KeyStoreTracker::instance()->getItems(); + d->busy = KeyStoreTracker::instance()->isBusy(); + d->items = KeyStoreTracker::instance()->getItems(); } //---------------------------------------------------------------------------- // KeyStoreInfo //---------------------------------------------------------------------------- class KeyStoreInfo::Private : public QSharedData { public: - KeyStore::Type type; - QString id, name; + KeyStore::Type type; + QString id, name; }; KeyStoreInfo::KeyStoreInfo() { } KeyStoreInfo::KeyStoreInfo(KeyStore::Type type, const QString &id, const QString &name) -:d(new Private) + : d(new Private) { - d->type = type; - d->id = id; - d->name = name; + d->type = type; + d->id = id; + d->name = name; } KeyStoreInfo::KeyStoreInfo(const KeyStoreInfo &from) -:d(from.d) + : d(from.d) { } KeyStoreInfo::~KeyStoreInfo() { } -KeyStoreInfo & KeyStoreInfo::operator=(const KeyStoreInfo &from) +KeyStoreInfo &KeyStoreInfo::operator=(const KeyStoreInfo &from) { - d = from.d; - return *this; + d = from.d; + return *this; } bool KeyStoreInfo::isNull() const { - return (d ? false: true); + return (d ? false : true); } KeyStore::Type KeyStoreInfo::type() const { - return d->type; + return d->type; } QString KeyStoreInfo::id() const { - return d->id; + return d->id; } QString KeyStoreInfo::name() const { - return d->name; + return d->name; } } diff --git a/src/qca_plugin.h b/src/qca_plugin.h --- a/src/qca_plugin.h +++ b/src/qca_plugin.h @@ -28,45 +28,46 @@ #include "qca_core.h" #include -namespace QCA { +namespace QCA +{ class ProviderItem; class ProviderManager { public: - ProviderManager(); - ~ProviderManager(); + ProviderManager(); + ~ProviderManager(); - void scan(); - bool add(Provider *p, int priority); - bool unload(const QString &name); - void unloadAll(); - void setDefault(Provider *p); - Provider *find(Provider *p) const; - Provider *find(const QString &name) const; - Provider *findFor(const QString &name, const QString &type) const; - void changePriority(const QString &name, int priority); - int getPriority(const QString &name); - QStringList allFeatures() const; - ProviderList providers() const; + void scan(); + bool add(Provider *p, int priority); + bool unload(const QString &name); + void unloadAll(); + void setDefault(Provider *p); + Provider *find(Provider *p) const; + Provider *find(const QString &name) const; + Provider *findFor(const QString &name, const QString &type) const; + void changePriority(const QString &name, int priority); + int getPriority(const QString &name); + QStringList allFeatures() const; + ProviderList providers() const; - static void mergeFeatures(QStringList *a, const QStringList &b); + static void mergeFeatures(QStringList *a, const QStringList &b); - QString diagnosticText() const; - void appendDiagnosticText(const QString &str); - void clearDiagnosticText(); + QString diagnosticText() const; + void appendDiagnosticText(const QString &str); + void clearDiagnosticText(); private: - mutable QMutex logMutex, providerMutex; - QString dtext; - QList providerItemList; - ProviderList providerList; - Provider *def; - bool scanned_static; - void addItem(ProviderItem *i, int priority); - bool haveAlready(const QString &name) const; - int get_default_priority(const QString &name) const; + mutable QMutex logMutex, providerMutex; + QString dtext; + QList providerItemList; + ProviderList providerList; + Provider *def; + bool scanned_static; + void addItem(ProviderItem *i, int priority); + bool haveAlready(const QString &name) const; + int get_default_priority(const QString &name) const; }; } diff --git a/src/qca_plugin.cpp b/src/qca_plugin.cpp --- a/src/qca_plugin.cpp +++ b/src/qca_plugin.cpp @@ -37,7 +37,8 @@ #define PLUGIN_SUBDIR "crypto" -namespace QCA { +namespace QCA +{ // from qca_core.cpp QVariantMap getProviderConfig_internal(Provider *p); @@ -50,762 +51,741 @@ // then throw out the top half, to nearest line. QString truncate_log(const QString &in, int size) { - if(size < 2 || in.length() < size) - return in; + if (size < 2 || in.length() < size) { + return in; + } - // start by pointing at the last chars - int at = in.length() - (size / 2); + // start by pointing at the last chars + int at = in.length() - (size / 2); - // if the previous char is a newline, then this is a perfect cut. - // otherwise, we need to skip to after the next newline. - if(in[at - 1] != '\n') - { - while(at < in.length() && in[at] != '\n') - { - ++at; - } + // if the previous char is a newline, then this is a perfect cut. + // otherwise, we need to skip to after the next newline. + if (in[at - 1] != '\n') { + while (at < in.length() && in[at] != '\n') { + ++at; + } - // at this point we either reached a newline, or end of - // the entire buffer + // at this point we either reached a newline, or end of + // the entire buffer - if(in[at] == '\n') - ++at; - } + if (in[at] == '\n') { + ++at; + } + } - return in.mid(at); + return in.mid(at); } static ProviderManager *g_pluginman = 0; static void logDebug(const QString &str) { - if(g_pluginman) - g_pluginman->appendDiagnosticText(str + '\n'); + if (g_pluginman) { + g_pluginman->appendDiagnosticText(str + '\n'); + } } static bool validVersion(int ver) { - // major version must be equal, minor version must be equal or lesser - if((ver & 0xff0000) == (QCA_VERSION & 0xff0000) - && (ver & 0xff00) <= (QCA_VERSION & 0xff00)) - return true; - return false; + // major version must be equal, minor version must be equal or lesser + if ((ver & 0xff0000) == (QCA_VERSION & 0xff0000) + && (ver & 0xff00) <= (QCA_VERSION & 0xff00)) { + return true; + } + return false; } class PluginInstance { private: - QPluginLoader *_loader; - QObject *_instance; - bool _ownInstance; + QPluginLoader *_loader; + QObject *_instance; + bool _ownInstance; - PluginInstance() - { - } + PluginInstance() + { + } public: - static PluginInstance *fromFile(const QString &fname, QString *errstr = 0) - { - QPluginLoader *loader = new QPluginLoader(fname); - if(!loader->load()) - { - if(errstr) - *errstr = QString("failed to load: %1").arg(loader->errorString()); - delete loader; - return 0; - } - QObject *obj = loader->instance(); - if(!obj) - { - if(errstr) - *errstr = "failed to get instance"; - loader->unload(); - delete loader; - return 0; - } - PluginInstance *i = new PluginInstance; - i->_loader = loader; - i->_instance = obj; - i->_ownInstance = true; - return i; - } - - static PluginInstance *fromStatic(QObject *obj) - { - PluginInstance *i = new PluginInstance; - i->_loader = 0; - i->_instance = obj; - i->_ownInstance = false; - return i; - } - - static PluginInstance *fromInstance(QObject *obj) - { - PluginInstance *i = new PluginInstance; - i->_loader = 0; - i->_instance = obj; - i->_ownInstance = true; - return i; - } - - ~PluginInstance() - { - if(_ownInstance) - delete _instance; - - if(_loader) - { - _loader->unload(); - delete _loader; - } - } - - void claim() - { - if(_loader) - _loader->moveToThread(0); - if(_ownInstance) - _instance->moveToThread(0); - } - - QObject *instance() - { - return _instance; - } + static PluginInstance *fromFile(const QString &fname, QString *errstr = 0) + { + QPluginLoader *loader = new QPluginLoader(fname); + if (!loader->load()) { + if (errstr) { + *errstr = QString("failed to load: %1").arg(loader->errorString()); + } + delete loader; + return 0; + } + QObject *obj = loader->instance(); + if (!obj) { + if (errstr) { + *errstr = "failed to get instance"; + } + loader->unload(); + delete loader; + return 0; + } + PluginInstance *i = new PluginInstance; + i->_loader = loader; + i->_instance = obj; + i->_ownInstance = true; + return i; + } + + static PluginInstance *fromStatic(QObject *obj) + { + PluginInstance *i = new PluginInstance; + i->_loader = 0; + i->_instance = obj; + i->_ownInstance = false; + return i; + } + + static PluginInstance *fromInstance(QObject *obj) + { + PluginInstance *i = new PluginInstance; + i->_loader = 0; + i->_instance = obj; + i->_ownInstance = true; + return i; + } + + ~PluginInstance() + { + if (_ownInstance) { + delete _instance; + } + + if (_loader) { + _loader->unload(); + delete _loader; + } + } + + void claim() + { + if (_loader) { + _loader->moveToThread(0); + } + if (_ownInstance) { + _instance->moveToThread(0); + } + } + + QObject *instance() + { + return _instance; + } }; class ProviderItem { public: - QString fname; - Provider *p; - int priority; - QMutex m; - - static ProviderItem *load(const QString &fname, QString *out_errstr = 0) - { - QString errstr; - PluginInstance *i = PluginInstance::fromFile(fname, &errstr); - if(!i) - { - if(out_errstr) - *out_errstr = errstr; - return 0; - } - QCAPlugin *plugin = qobject_cast(i->instance()); - if(!plugin) - { - if(out_errstr) - *out_errstr = "does not offer QCAPlugin interface"; - delete i; - return 0; - } - - Provider *p = plugin->createProvider(); - if(!p) - { - if(out_errstr) - *out_errstr = "unable to create provider"; - delete i; - return 0; - } - - ProviderItem *pi = new ProviderItem(i, p); - pi->fname = fname; - return pi; - } - - static ProviderItem *loadStatic(QObject *instance, QString *errstr = 0) - { - PluginInstance *i = PluginInstance::fromStatic(instance); - QCAPlugin *plugin = qobject_cast(i->instance()); - if(!plugin) - { - if(errstr) - *errstr = "does not offer QCAPlugin interface"; - delete i; - return 0; - } - - Provider *p = plugin->createProvider(); - if(!p) - { - if(errstr) - *errstr = "unable to create provider"; - delete i; - return 0; - } - - ProviderItem *pi = new ProviderItem(i, p); - return pi; - } - - static ProviderItem *fromClass(Provider *p) - { - ProviderItem *pi = new ProviderItem(0, p); - return pi; - } - - ~ProviderItem() - { - delete p; - delete instance; - } - - void ensureInit() - { - QMutexLocker locker(&m); - if(init_done) - return; - init_done = true; - - p->init(); - - // load config - QVariantMap conf = getProviderConfig_internal(p); - if(!conf.isEmpty()) - p->configChanged(conf); - } - - bool initted() const - { - return init_done; - } - - // null if not a plugin - QObject *objectInstance() const - { - if(instance) - return instance->instance(); - else - return 0; - } + QString fname; + Provider *p; + int priority; + QMutex m; + + static ProviderItem *load(const QString &fname, QString *out_errstr = 0) + { + QString errstr; + PluginInstance *i = PluginInstance::fromFile(fname, &errstr); + if (!i) { + if (out_errstr) { + *out_errstr = errstr; + } + return 0; + } + QCAPlugin *plugin = qobject_cast(i->instance()); + if (!plugin) { + if (out_errstr) { + *out_errstr = "does not offer QCAPlugin interface"; + } + delete i; + return 0; + } + + Provider *p = plugin->createProvider(); + if (!p) { + if (out_errstr) { + *out_errstr = "unable to create provider"; + } + delete i; + return 0; + } + + ProviderItem *pi = new ProviderItem(i, p); + pi->fname = fname; + return pi; + } + + static ProviderItem *loadStatic(QObject *instance, QString *errstr = 0) + { + PluginInstance *i = PluginInstance::fromStatic(instance); + QCAPlugin *plugin = qobject_cast(i->instance()); + if (!plugin) { + if (errstr) { + *errstr = "does not offer QCAPlugin interface"; + } + delete i; + return 0; + } + + Provider *p = plugin->createProvider(); + if (!p) { + if (errstr) { + *errstr = "unable to create provider"; + } + delete i; + return 0; + } + + ProviderItem *pi = new ProviderItem(i, p); + return pi; + } + + static ProviderItem *fromClass(Provider *p) + { + ProviderItem *pi = new ProviderItem(0, p); + return pi; + } + + ~ProviderItem() + { + delete p; + delete instance; + } + + void ensureInit() + { + QMutexLocker locker(&m); + if (init_done) { + return; + } + init_done = true; + + p->init(); + + // load config + QVariantMap conf = getProviderConfig_internal(p); + if (!conf.isEmpty()) { + p->configChanged(conf); + } + } + + bool initted() const + { + return init_done; + } + + // null if not a plugin + QObject *objectInstance() const + { + if (instance) { + return instance->instance(); + } else { + return 0; + } + } private: - PluginInstance *instance; - bool init_done; - - ProviderItem(PluginInstance *_instance, Provider *_p) - { - instance = _instance; - p = _p; - init_done = false; - - // disassociate from threads - if(instance) - instance->claim(); - } + PluginInstance *instance; + bool init_done; + + ProviderItem(PluginInstance *_instance, Provider *_p) + { + instance = _instance; + p = _p; + init_done = false; + + // disassociate from threads + if (instance) { + instance->claim(); + } + } }; ProviderManager::ProviderManager() { - g_pluginman = this; - def = 0; - scanned_static = false; + g_pluginman = this; + def = 0; + scanned_static = false; } ProviderManager::~ProviderManager() { - if(def) - def->deinit(); - unloadAll(); - delete def; - g_pluginman = 0; + if (def) { + def->deinit(); + } + unloadAll(); + delete def; + g_pluginman = 0; } void ProviderManager::scan() { - QMutexLocker locker(&providerMutex); - - // check static first, but only once - if(!scanned_static) - { - logDebug("Checking Qt static plugins:"); - QObjectList list = QPluginLoader::staticInstances(); - if(list.isEmpty()) - logDebug(" (none)"); - for(int n = 0; n < list.count(); ++n) - { - QObject *instance = list[n]; - QString className = QString::fromLatin1(instance->metaObject()->className()); - - QString errstr; - ProviderItem *i = ProviderItem::loadStatic(instance, &errstr); - if(!i) - { - logDebug(QString(" %1: %2").arg(className, errstr)); - continue; - } - - QString providerName = i->p->name(); - if(haveAlready(providerName)) - { - logDebug(QString(" %1: (as %2) already loaded provider, skipping").arg(className, providerName)); - delete i; - continue; - } - - int ver = i->p->qcaVersion(); - if(!validVersion(ver)) - { - errstr.sprintf("plugin version 0x%06x is in the future", ver); - logDebug(QString(" %1: (as %2) %3").arg(className, providerName, errstr)); - delete i; - continue; - } - - addItem(i, get_default_priority(providerName)); - logDebug(QString(" %1: loaded as %2").arg(className, providerName)); - } - scanned_static = true; - } + QMutexLocker locker(&providerMutex); + + // check static first, but only once + if (!scanned_static) { + logDebug("Checking Qt static plugins:"); + QObjectList list = QPluginLoader::staticInstances(); + if (list.isEmpty()) { + logDebug(" (none)"); + } + for (int n = 0; n < list.count(); ++n) { + QObject *instance = list[n]; + QString className = QString::fromLatin1(instance->metaObject()->className()); + + QString errstr; + ProviderItem *i = ProviderItem::loadStatic(instance, &errstr); + if (!i) { + logDebug(QString(" %1: %2").arg(className, errstr)); + continue; + } + + QString providerName = i->p->name(); + if (haveAlready(providerName)) { + logDebug(QString(" %1: (as %2) already loaded provider, skipping").arg(className, providerName)); + delete i; + continue; + } + + int ver = i->p->qcaVersion(); + if (!validVersion(ver)) { + errstr.sprintf("plugin version 0x%06x is in the future", ver); + logDebug(QString(" %1: (as %2) %3").arg(className, providerName, errstr)); + delete i; + continue; + } + + addItem(i, get_default_priority(providerName)); + logDebug(QString(" %1: loaded as %2").arg(className, providerName)); + } + scanned_static = true; + } #ifndef QCA_NO_PLUGINS - if(qgetenv("QCA_NO_PLUGINS") == "1") - return; - - const QStringList dirs = pluginPaths(); - if(dirs.isEmpty()) - logDebug("No Qt Library Paths"); - for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) - { + if (qgetenv("QCA_NO_PLUGINS") == "1") { + return; + } + + const QStringList dirs = pluginPaths(); + if (dirs.isEmpty()) { + logDebug("No Qt Library Paths"); + } + for (QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) { #ifdef DEVELOPER_MODE - logDebug(QString("Checking QCA build tree Path: %1").arg(QDir::toNativeSeparators(*it))); + logDebug(QString("Checking QCA build tree Path: %1").arg(QDir::toNativeSeparators(*it))); #else - logDebug(QString("Checking Qt Library Path: %1").arg(QDir::toNativeSeparators(*it))); + logDebug(QString("Checking Qt Library Path: %1").arg(QDir::toNativeSeparators(*it))); #endif - QDir libpath(*it); - QDir dir(libpath.filePath(PLUGIN_SUBDIR)); - if(!dir.exists()) - { - logDebug(" (No 'crypto' subdirectory)"); - continue; - } - - QStringList entryList = dir.entryList(QDir::Files); - if(entryList.isEmpty()) - { - logDebug(" (No files in 'crypto' subdirectory)"); - continue; - } - - foreach(const QString &maybeFile, entryList) - { - QFileInfo fi(dir.filePath(maybeFile)); - - QString filePath = fi.filePath(); // file name with path - QString fileName = fi.fileName(); // just file name - - if(!QLibrary::isLibrary(filePath)) - { - logDebug(QString(" %1: not a library, skipping").arg(fileName)); - continue; - } - - // make sure we haven't loaded this file before - bool haveFile = false; - for(int n = 0; n < providerItemList.count(); ++n) - { - ProviderItem *pi = providerItemList[n]; - if(!pi->fname.isEmpty() && pi->fname == filePath) - { - haveFile = true; - break; - } - } - if(haveFile) - { - logDebug(QString(" %1: already loaded file, skipping").arg(fileName)); - continue; - } - - QString errstr; - ProviderItem *i = ProviderItem::load(filePath, &errstr); - if(!i) - { - logDebug(QString(" %1: %2").arg(fileName, errstr)); - continue; - } - - QString className = QString::fromLatin1(i->objectInstance()->metaObject()->className()); - - QString providerName = i->p->name(); - if(haveAlready(providerName)) - { - logDebug(QString(" %1: (class: %2, as %3) already loaded provider, skipping").arg(fileName, className, providerName)); - delete i; - continue; - } - - int ver = i->p->qcaVersion(); - if(!validVersion(ver)) - { - errstr.sprintf("plugin version 0x%06x is in the future", ver); - logDebug(QString(" %1: (class: %2, as %3) %4").arg(fileName, className, providerName, errstr)); - delete i; - continue; - } - - if(skip_plugins(def).contains(providerName)) - { - logDebug(QString(" %1: (class: %2, as %3) explicitly disabled, skipping").arg(fileName, className, providerName)); - delete i; - continue; - } - - addItem(i, get_default_priority(providerName)); - logDebug(QString(" %1: (class: %2) loaded as %3").arg(fileName, className, providerName)); - } - } + QDir libpath(*it); + QDir dir(libpath.filePath(PLUGIN_SUBDIR)); + if (!dir.exists()) { + logDebug(" (No 'crypto' subdirectory)"); + continue; + } + + QStringList entryList = dir.entryList(QDir::Files); + if (entryList.isEmpty()) { + logDebug(" (No files in 'crypto' subdirectory)"); + continue; + } + + foreach (const QString &maybeFile, entryList) { + QFileInfo fi(dir.filePath(maybeFile)); + + QString filePath = fi.filePath(); // file name with path + QString fileName = fi.fileName(); // just file name + + if (!QLibrary::isLibrary(filePath)) { + logDebug(QString(" %1: not a library, skipping").arg(fileName)); + continue; + } + + // make sure we haven't loaded this file before + bool haveFile = false; + for (int n = 0; n < providerItemList.count(); ++n) { + ProviderItem *pi = providerItemList[n]; + if (!pi->fname.isEmpty() && pi->fname == filePath) { + haveFile = true; + break; + } + } + if (haveFile) { + logDebug(QString(" %1: already loaded file, skipping").arg(fileName)); + continue; + } + + QString errstr; + ProviderItem *i = ProviderItem::load(filePath, &errstr); + if (!i) { + logDebug(QString(" %1: %2").arg(fileName, errstr)); + continue; + } + + QString className = QString::fromLatin1(i->objectInstance()->metaObject()->className()); + + QString providerName = i->p->name(); + if (haveAlready(providerName)) { + logDebug(QString(" %1: (class: %2, as %3) already loaded provider, skipping").arg(fileName, className, providerName)); + delete i; + continue; + } + + int ver = i->p->qcaVersion(); + if (!validVersion(ver)) { + errstr.sprintf("plugin version 0x%06x is in the future", ver); + logDebug(QString(" %1: (class: %2, as %3) %4").arg(fileName, className, providerName, errstr)); + delete i; + continue; + } + + if (skip_plugins(def).contains(providerName)) { + logDebug(QString(" %1: (class: %2, as %3) explicitly disabled, skipping").arg(fileName, className, providerName)); + delete i; + continue; + } + + addItem(i, get_default_priority(providerName)); + logDebug(QString(" %1: (class: %2) loaded as %3").arg(fileName, className, providerName)); + } + } #endif } bool ProviderManager::add(Provider *p, int priority) { - QMutexLocker locker(&providerMutex); - - QString providerName = p->name(); - - if(haveAlready(providerName)) - { - logDebug(QString("Directly adding: %1: already loaded provider, skipping").arg(providerName)); - return false; - } - - int ver = p->qcaVersion(); - if(!validVersion(ver)) - { - QString errstr; - errstr.sprintf("plugin version 0x%06x is in the future", ver); - logDebug(QString("Directly adding: %1: %2").arg(providerName, errstr)); - return false; - } - - ProviderItem *i = ProviderItem::fromClass(p); - addItem(i, priority); - logDebug(QString("Directly adding: %1: loaded").arg(providerName)); - return true; + QMutexLocker locker(&providerMutex); + + QString providerName = p->name(); + + if (haveAlready(providerName)) { + logDebug(QString("Directly adding: %1: already loaded provider, skipping").arg(providerName)); + return false; + } + + int ver = p->qcaVersion(); + if (!validVersion(ver)) { + QString errstr; + errstr.sprintf("plugin version 0x%06x is in the future", ver); + logDebug(QString("Directly adding: %1: %2").arg(providerName, errstr)); + return false; + } + + ProviderItem *i = ProviderItem::fromClass(p); + addItem(i, priority); + logDebug(QString("Directly adding: %1: loaded").arg(providerName)); + return true; } bool ProviderManager::unload(const QString &name) { - for(int n = 0; n < providerItemList.count(); ++n) - { - ProviderItem *i = providerItemList[n]; - if(i->p && i->p->name() == name) - { - if(i->initted()) - i->p->deinit(); - - delete i; - providerItemList.removeAt(n); - providerList.removeAt(n); - - logDebug(QString("Unloaded: %1").arg(name)); - return true; - } - } - - return false; + for (int n = 0; n < providerItemList.count(); ++n) { + ProviderItem *i = providerItemList[n]; + if (i->p && i->p->name() == name) { + if (i->initted()) { + i->p->deinit(); + } + + delete i; + providerItemList.removeAt(n); + providerList.removeAt(n); + + logDebug(QString("Unloaded: %1").arg(name)); + return true; + } + } + + return false; } void ProviderManager::unloadAll() { - foreach(ProviderItem *i, providerItemList) - { - if(i->initted()) - i->p->deinit(); - } - - while(!providerItemList.isEmpty()) - { - ProviderItem *i = providerItemList.first(); - QString name = i->p->name(); - delete i; - providerItemList.removeFirst(); - providerList.removeFirst(); - - logDebug(QString("Unloaded: %1").arg(name)); - } + foreach (ProviderItem *i, providerItemList) { + if (i->initted()) { + i->p->deinit(); + } + } + + while (!providerItemList.isEmpty()) { + ProviderItem *i = providerItemList.first(); + QString name = i->p->name(); + delete i; + providerItemList.removeFirst(); + providerList.removeFirst(); + + logDebug(QString("Unloaded: %1").arg(name)); + } } void ProviderManager::setDefault(Provider *p) { - QMutexLocker locker(&providerMutex); - - if(def) - delete def; - def = p; - if(def) - { - def->init(); - QVariantMap conf = getProviderConfig_internal(def); - if(!conf.isEmpty()) - def->configChanged(conf); - } + QMutexLocker locker(&providerMutex); + + if (def) { + delete def; + } + def = p; + if (def) { + def->init(); + QVariantMap conf = getProviderConfig_internal(def); + if (!conf.isEmpty()) { + def->configChanged(conf); + } + } } Provider *ProviderManager::find(Provider *_p) const { - ProviderItem *i = 0; - Provider *p = 0; - - providerMutex.lock(); - if(_p == def) - { - p = def; - } - else - { - for(int n = 0; n < providerItemList.count(); ++n) - { - ProviderItem *pi = providerItemList[n]; - if(pi->p && pi->p == _p) - { - i = pi; - p = pi->p; - break; - } - } - } - providerMutex.unlock(); - - if(i) - i->ensureInit(); - return p; + ProviderItem *i = 0; + Provider *p = 0; + + providerMutex.lock(); + if (_p == def) { + p = def; + } else { + for (int n = 0; n < providerItemList.count(); ++n) { + ProviderItem *pi = providerItemList[n]; + if (pi->p && pi->p == _p) { + i = pi; + p = pi->p; + break; + } + } + } + providerMutex.unlock(); + + if (i) { + i->ensureInit(); + } + return p; } Provider *ProviderManager::find(const QString &name) const { - ProviderItem *i = 0; - Provider *p = 0; - - providerMutex.lock(); - if(def && name == def->name()) - { - p = def; - } - else - { - for(int n = 0; n < providerItemList.count(); ++n) - { - ProviderItem *pi = providerItemList[n]; - if(pi->p && pi->p->name() == name) - { - i = pi; - p = pi->p; - break; - } - } - } - providerMutex.unlock(); - - if(i) - i->ensureInit(); - return p; + ProviderItem *i = 0; + Provider *p = 0; + + providerMutex.lock(); + if (def && name == def->name()) { + p = def; + } else { + for (int n = 0; n < providerItemList.count(); ++n) { + ProviderItem *pi = providerItemList[n]; + if (pi->p && pi->p->name() == name) { + i = pi; + p = pi->p; + break; + } + } + } + providerMutex.unlock(); + + if (i) { + i->ensureInit(); + } + return p; } Provider *ProviderManager::findFor(const QString &name, const QString &type) const { - if(name.isEmpty()) - { - providerMutex.lock(); - QList list = providerItemList; - providerMutex.unlock(); - - // find the first one that can do it - for(int n = 0; n < list.count(); ++n) - { - ProviderItem *pi = list[n]; - pi->ensureInit(); - if(pi->p && pi->p->features().contains(type)) - return pi->p; - } - - // try the default provider as a last resort - providerMutex.lock(); - Provider *p = def; - providerMutex.unlock(); - if(p && p->features().contains(type)) - return p; - - return 0; - } - else - { - Provider *p = find(name); - if(p && p->features().contains(type)) - return p; - return 0; - } + if (name.isEmpty()) { + providerMutex.lock(); + QList list = providerItemList; + providerMutex.unlock(); + + // find the first one that can do it + for (int n = 0; n < list.count(); ++n) { + ProviderItem *pi = list[n]; + pi->ensureInit(); + if (pi->p && pi->p->features().contains(type)) { + return pi->p; + } + } + + // try the default provider as a last resort + providerMutex.lock(); + Provider *p = def; + providerMutex.unlock(); + if (p && p->features().contains(type)) { + return p; + } + + return 0; + } else { + Provider *p = find(name); + if (p && p->features().contains(type)) { + return p; + } + return 0; + } } void ProviderManager::changePriority(const QString &name, int priority) { - QMutexLocker locker(&providerMutex); - - ProviderItem *i = 0; - int n = 0; - for(; n < providerItemList.count(); ++n) - { - ProviderItem *pi = providerItemList[n]; - if(pi->p && pi->p->name() == name) - { - i = pi; - break; - } - } - if(!i) - return; - - providerItemList.removeAt(n); - providerList.removeAt(n); - - addItem(i, priority); + QMutexLocker locker(&providerMutex); + + ProviderItem *i = 0; + int n = 0; + for (; n < providerItemList.count(); ++n) { + ProviderItem *pi = providerItemList[n]; + if (pi->p && pi->p->name() == name) { + i = pi; + break; + } + } + if (!i) { + return; + } + + providerItemList.removeAt(n); + providerList.removeAt(n); + + addItem(i, priority); } int ProviderManager::getPriority(const QString &name) { - QMutexLocker locker(&providerMutex); - - ProviderItem *i = 0; - for(int n = 0; n < providerItemList.count(); ++n) - { - ProviderItem *pi = providerItemList[n]; - if(pi->p && pi->p->name() == name) - { - i = pi; - break; - } - } - if(!i) - return -1; - - return i->priority; + QMutexLocker locker(&providerMutex); + + ProviderItem *i = 0; + for (int n = 0; n < providerItemList.count(); ++n) { + ProviderItem *pi = providerItemList[n]; + if (pi->p && pi->p->name() == name) { + i = pi; + break; + } + } + if (!i) { + return -1; + } + + return i->priority; } QStringList ProviderManager::allFeatures() const { - QStringList featureList; - - providerMutex.lock(); - Provider *p = def; - providerMutex.unlock(); - if(p) - featureList = p->features(); - - providerMutex.lock(); - QList list = providerItemList; - providerMutex.unlock(); - for(int n = 0; n < list.count(); ++n) - { - ProviderItem *i = list[n]; - if(i->p) - mergeFeatures(&featureList, i->p->features()); - } - - return featureList; + QStringList featureList; + + providerMutex.lock(); + Provider *p = def; + providerMutex.unlock(); + if (p) { + featureList = p->features(); + } + + providerMutex.lock(); + QList list = providerItemList; + providerMutex.unlock(); + for (int n = 0; n < list.count(); ++n) { + ProviderItem *i = list[n]; + if (i->p) { + mergeFeatures(&featureList, i->p->features()); + } + } + + return featureList; } ProviderList ProviderManager::providers() const { - QMutexLocker locker(&providerMutex); + QMutexLocker locker(&providerMutex); - return providerList; + return providerList; } QString ProviderManager::diagnosticText() const { - QMutexLocker locker(&logMutex); + QMutexLocker locker(&logMutex); - return dtext; + return dtext; } void ProviderManager::appendDiagnosticText(const QString &str) { - QMutexLocker locker(&logMutex); + QMutexLocker locker(&logMutex); - dtext += str; - dtext = truncate_log(dtext, 20000); + dtext += str; + dtext = truncate_log(dtext, 20000); } void ProviderManager::clearDiagnosticText() { - QMutexLocker locker(&logMutex); + QMutexLocker locker(&logMutex); - dtext = QString(); + dtext = QString(); } void ProviderManager::addItem(ProviderItem *item, int priority) { - if(priority < 0) - { - // for -1, make the priority the same as the last item - if(!providerItemList.isEmpty()) - { - ProviderItem *last = providerItemList.last(); - item->priority = last->priority; - } - else - item->priority = 0; - - providerItemList.append(item); - providerList.append(item->p); - } - else - { - // place the item before any other items with same or greater priority - int n = 0; - for(; n < providerItemList.count(); ++n) - { - ProviderItem *i = providerItemList[n]; - if(i->priority >= priority) - break; - } - - item->priority = priority; - providerItemList.insert(n, item); - providerList.insert(n, item->p); - } + if (priority < 0) { + // for -1, make the priority the same as the last item + if (!providerItemList.isEmpty()) { + ProviderItem *last = providerItemList.last(); + item->priority = last->priority; + } else { + item->priority = 0; + } + + providerItemList.append(item); + providerList.append(item->p); + } else { + // place the item before any other items with same or greater priority + int n = 0; + for (; n < providerItemList.count(); ++n) { + ProviderItem *i = providerItemList[n]; + if (i->priority >= priority) { + break; + } + } + + item->priority = priority; + providerItemList.insert(n, item); + providerList.insert(n, item->p); + } } bool ProviderManager::haveAlready(const QString &name) const { - if(def && name == def->name()) - return true; - - for(int n = 0; n < providerItemList.count(); ++n) - { - ProviderItem *pi = providerItemList[n]; - if(pi->p && pi->p->name() == name) - return true; - } - - return false; + if (def && name == def->name()) { + return true; + } + + for (int n = 0; n < providerItemList.count(); ++n) { + ProviderItem *pi = providerItemList[n]; + if (pi->p && pi->p->name() == name) { + return true; + } + } + + return false; } void ProviderManager::mergeFeatures(QStringList *a, const QStringList &b) { - for(QStringList::ConstIterator it = b.begin(); it != b.end(); ++it) - { - if(!a->contains(*it)) - a->append(*it); - } + for (QStringList::ConstIterator it = b.begin(); it != b.end(); ++it) { + if (!a->contains(*it)) { + a->append(*it); + } + } } int ProviderManager::get_default_priority(const QString &name) const { - QStringList list = plugin_priorities(def); - foreach(const QString &s, list) - { - // qca_default already sanity checks the strings - int n = s.indexOf(':'); - QString sname = s.mid(0, n); - int spriority = s.mid(n + 1).toInt(); - if(sname == name) - return spriority; - } - return -1; + QStringList list = plugin_priorities(def); + foreach (const QString &s, list) { + // qca_default already sanity checks the strings + int n = s.indexOf(':'); + QString sname = s.mid(0, n); + int spriority = s.mid(n + 1).toInt(); + if (sname == name) { + return spriority; + } + } + return -1; } } diff --git a/src/qca_publickey.cpp b/src/qca_publickey.cpp --- a/src/qca_publickey.cpp +++ b/src/qca_publickey.cpp @@ -26,525 +26,544 @@ #include #include -namespace QCA { +namespace QCA +{ Provider::Context *getContext(const QString &type, const QString &provider); Provider::Context *getContext(const QString &type, Provider *p); bool stringToFile(const QString &fileName, const QString &content) { - QFile f(fileName); - if(!f.open(QFile::WriteOnly)) - return false; - QTextStream ts(&f); - ts << content; - return true; + QFile f(fileName); + if (!f.open(QFile::WriteOnly)) { + return false; + } + QTextStream ts(&f); + ts << content; + return true; } bool stringFromFile(const QString &fileName, QString *s) { - QFile f(fileName); - if(!f.open(QFile::ReadOnly)) - return false; - QTextStream ts(&f); - *s = ts.readAll(); - return true; + QFile f(fileName); + if (!f.open(QFile::ReadOnly)) { + return false; + } + QTextStream ts(&f); + *s = ts.readAll(); + return true; } bool arrayToFile(const QString &fileName, const QByteArray &content) { - QFile f(fileName); - if(!f.open(QFile::WriteOnly)) - return false; - f.write(content.data(), content.size()); - return true; + QFile f(fileName); + if (!f.open(QFile::WriteOnly)) { + return false; + } + f.write(content.data(), content.size()); + return true; } bool arrayFromFile(const QString &fileName, QByteArray *a) { - QFile f(fileName); - if(!f.open(QFile::ReadOnly)) - return false; - *a = f.readAll(); - return true; + QFile f(fileName); + if (!f.open(QFile::ReadOnly)) { + return false; + } + *a = f.readAll(); + return true; } bool ask_passphrase(const QString &fname, void *ptr, SecureArray *answer) { - PasswordAsker asker; - asker.ask(Event::StylePassphrase, fname, ptr); - asker.waitForResponse(); - if(!asker.accepted()) - return false; - *answer = asker.password(); - return true; + PasswordAsker asker; + asker.ask(Event::StylePassphrase, fname, ptr); + asker.waitForResponse(); + if (!asker.accepted()) { + return false; + } + *answer = asker.password(); + return true; } ProviderList allProviders() { - ProviderList pl = providers(); - pl += defaultProvider(); - return pl; + ProviderList pl = providers(); + pl += defaultProvider(); + return pl; } Provider *providerForName(const QString &name) { - ProviderList pl = allProviders(); - for(int n = 0; n < pl.count(); ++n) - { - if(pl[n]->name() == name) - return pl[n]; - } - return 0; + ProviderList pl = allProviders(); + for (int n = 0; n < pl.count(); ++n) { + if (pl[n]->name() == name) { + return pl[n]; + } + } + return 0; } bool use_asker_fallback(ConvertResult r) { - // FIXME: we should only do this if we get ErrorPassphrase? - //if(r == ErrorPassphrase) - if(r != ConvertGood) - return true; - return false; + // FIXME: we should only do this if we get ErrorPassphrase? + //if(r == ErrorPassphrase) + if (r != ConvertGood) { + return true; + } + return false; } class Getter_GroupSet { public: - static QList getList(Provider *p) - { - QList list; - const DLGroupContext *c = static_cast(getContext("dlgroup", p)); - if(!c) - return list; - list = c->supportedGroupSets(); - delete c; - return list; - } + static QList getList(Provider *p) + { + QList list; + const DLGroupContext *c = static_cast(getContext("dlgroup", p)); + if (!c) { + return list; + } + list = c->supportedGroupSets(); + delete c; + return list; + } }; class Getter_PBE { public: - static QList getList(Provider *p) - { - QList list; - const PKeyContext *c = static_cast(getContext("pkey", p)); - if(!c) - return list; - list = c->supportedPBEAlgorithms(); - delete c; - return list; - } + static QList getList(Provider *p) + { + QList list; + const PKeyContext *c = static_cast(getContext("pkey", p)); + if (!c) { + return list; + } + list = c->supportedPBEAlgorithms(); + delete c; + return list; + } }; class Getter_Type { public: - static QList getList(Provider *p) - { - QList list; - const PKeyContext *c = static_cast(getContext("pkey", p)); - if(!c) - return list; - list = c->supportedTypes(); - delete c; - return list; - } + static QList getList(Provider *p) + { + QList list; + const PKeyContext *c = static_cast(getContext("pkey", p)); + if (!c) { + return list; + } + list = c->supportedTypes(); + delete c; + return list; + } }; class Getter_IOType { public: - static QList getList(Provider *p) - { - QList list; - const PKeyContext *c = static_cast(getContext("pkey", p)); - if(!c) - return list; - list = c->supportedIOTypes(); - delete c; - return list; - } + static QList getList(Provider *p) + { + QList list; + const PKeyContext *c = static_cast(getContext("pkey", p)); + if (!c) { + return list; + } + list = c->supportedIOTypes(); + delete c; + return list; + } }; template class Getter_PublicKey { public: - // DER - static ConvertResult fromData(PKeyContext *c, const QByteArray &in) - { - return c->publicFromDER(in); - } - - // PEM - static ConvertResult fromData(PKeyContext *c, const QString &in) - { - return c->publicFromPEM(in); - } - - static PublicKey getKey(Provider *p, const I &in, const SecureArray &, ConvertResult *result) - { - PublicKey k; - PKeyContext *c = static_cast(getContext("pkey", p)); - if(!c) - { - if(result) - *result = ErrorDecode; - return k; - } - ConvertResult r = fromData(c, in); - if(result) - *result = r; - if(r == ConvertGood) - k.change(c); - else - delete c; - return k; - } + // DER + static ConvertResult fromData(PKeyContext *c, const QByteArray &in) + { + return c->publicFromDER(in); + } + + // PEM + static ConvertResult fromData(PKeyContext *c, const QString &in) + { + return c->publicFromPEM(in); + } + + static PublicKey getKey(Provider *p, const I &in, const SecureArray &, ConvertResult *result) + { + PublicKey k; + PKeyContext *c = static_cast(getContext("pkey", p)); + if (!c) { + if (result) { + *result = ErrorDecode; + } + return k; + } + ConvertResult r = fromData(c, in); + if (result) { + *result = r; + } + if (r == ConvertGood) { + k.change(c); + } else { + delete c; + } + return k; + } }; template class Getter_PrivateKey { public: - // DER - static ConvertResult fromData(PKeyContext *c, const SecureArray &in, const SecureArray &passphrase) - { - return c->privateFromDER(in, passphrase); - } - - // PEM - static ConvertResult fromData(PKeyContext *c, const QString &in, const SecureArray &passphrase) - { - return c->privateFromPEM(in, passphrase); - } - - static PrivateKey getKey(Provider *p, const I &in, const SecureArray &passphrase, ConvertResult *result) - { - PrivateKey k; - PKeyContext *c = static_cast(getContext("pkey", p)); - if(!c) - { - if(result) - *result = ErrorDecode; - return k; - } - ConvertResult r = fromData(c, in, passphrase); - if(result) - *result = r; - if(r == ConvertGood) - k.change(c); - else - delete c; - return k; - } + // DER + static ConvertResult fromData(PKeyContext *c, const SecureArray &in, const SecureArray &passphrase) + { + return c->privateFromDER(in, passphrase); + } + + // PEM + static ConvertResult fromData(PKeyContext *c, const QString &in, const SecureArray &passphrase) + { + return c->privateFromPEM(in, passphrase); + } + + static PrivateKey getKey(Provider *p, const I &in, const SecureArray &passphrase, ConvertResult *result) + { + PrivateKey k; + PKeyContext *c = static_cast(getContext("pkey", p)); + if (!c) { + if (result) { + *result = ErrorDecode; + } + return k; + } + ConvertResult r = fromData(c, in, passphrase); + if (result) { + *result = r; + } + if (r == ConvertGood) { + k.change(c); + } else { + delete c; + } + return k; + } }; Provider *providerForGroupSet(DLGroupSet set) { - ProviderList pl = allProviders(); - for(int n = 0; n < pl.count(); ++n) - { - if(Getter_GroupSet::getList(pl[n]).contains(set)) - return pl[n]; - } - return 0; + ProviderList pl = allProviders(); + for (int n = 0; n < pl.count(); ++n) { + if (Getter_GroupSet::getList(pl[n]).contains(set)) { + return pl[n]; + } + } + return 0; } Provider *providerForPBE(PBEAlgorithm alg, PKey::Type ioType, const PKeyContext *prefer = 0) { - Provider *preferProvider = 0; - if(prefer) - { - preferProvider = prefer->provider(); - if(prefer->supportedPBEAlgorithms().contains(alg) && prefer->supportedIOTypes().contains(ioType)) - return preferProvider; - } + Provider *preferProvider = 0; + if (prefer) { + preferProvider = prefer->provider(); + if (prefer->supportedPBEAlgorithms().contains(alg) && prefer->supportedIOTypes().contains(ioType)) { + return preferProvider; + } + } - ProviderList pl = allProviders(); - for(int n = 0; n < pl.count(); ++n) - { - if(preferProvider && pl[n] == preferProvider) - continue; + ProviderList pl = allProviders(); + for (int n = 0; n < pl.count(); ++n) { + if (preferProvider && pl[n] == preferProvider) { + continue; + } - if(Getter_PBE::getList(pl[n]).contains(alg) && Getter_IOType::getList(pl[n]).contains(ioType)) - return pl[n]; - } - return 0; + if (Getter_PBE::getList(pl[n]).contains(alg) && Getter_IOType::getList(pl[n]).contains(ioType)) { + return pl[n]; + } + } + return 0; } Provider *providerForIOType(PKey::Type type, const PKeyContext *prefer = 0) { - Provider *preferProvider = 0; - if(prefer) - { - preferProvider = prefer->provider(); - if(prefer && prefer->supportedIOTypes().contains(type)) - return preferProvider; - } + Provider *preferProvider = 0; + if (prefer) { + preferProvider = prefer->provider(); + if (prefer && prefer->supportedIOTypes().contains(type)) { + return preferProvider; + } + } - ProviderList pl = allProviders(); - for(int n = 0; n < pl.count(); ++n) - { - if(preferProvider && pl[n] == preferProvider) - continue; + ProviderList pl = allProviders(); + for (int n = 0; n < pl.count(); ++n) { + if (preferProvider && pl[n] == preferProvider) { + continue; + } - if(Getter_IOType::getList(pl[n]).contains(type)) - return pl[n]; - } - return 0; + if (Getter_IOType::getList(pl[n]).contains(type)) { + return pl[n]; + } + } + return 0; } template QList getList(const QString &provider) { - QList list; - - // single - if(!provider.isEmpty()) - { - Provider *p = providerForName(provider); - if(p) - list = G::getList(p); - } - // all - else - { - ProviderList pl = allProviders(); - for(int n = 0; n < pl.count(); ++n) - { - QList other = G::getList(pl[n]); - for(int k = 0; k < other.count(); ++k) - { - // only add what we don't have in the list - if(!list.contains(other[k])) - list += other[k]; - } - } - } - - return list; + QList list; + + // single + if (!provider.isEmpty()) { + Provider *p = providerForName(provider); + if (p) { + list = G::getList(p); + } + } + // all + else { + ProviderList pl = allProviders(); + for (int n = 0; n < pl.count(); ++n) { + QList other = G::getList(pl[n]); + for (int k = 0; k < other.count(); ++k) { + // only add what we don't have in the list + if (!list.contains(other[k])) { + list += other[k]; + } + } + } + } + + return list; } template T getKey(const QString &provider, const I &in, const SecureArray &passphrase, ConvertResult *result) { - T k; - - // single - if(!provider.isEmpty()) - { - Provider *p = providerForName(provider); - if(!p) - return k; - k = G::getKey(p, in, passphrase, result); - } - // all - else - { - ProviderList pl = allProviders(); - for(int n = 0; n < pl.count(); ++n) - { - ConvertResult r; - k = G::getKey(pl[n], in, passphrase, &r); - if(result) - *result = r; - if(!k.isNull()) - break; - if(r == ErrorPassphrase) // don't loop if we get this - break; - } - } - - return k; + T k; + + // single + if (!provider.isEmpty()) { + Provider *p = providerForName(provider); + if (!p) { + return k; + } + k = G::getKey(p, in, passphrase, result); + } + // all + else { + ProviderList pl = allProviders(); + for (int n = 0; n < pl.count(); ++n) { + ConvertResult r; + k = G::getKey(pl[n], in, passphrase, &r); + if (result) { + *result = r; + } + if (!k.isNull()) { + break; + } + if (r == ErrorPassphrase) { // don't loop if we get this + break; + } + } + } + + return k; } PBEAlgorithm get_pbe_default() { - return PBES2_TripleDES_SHA1; + return PBES2_TripleDES_SHA1; } static PrivateKey get_privatekey_der(const SecureArray &der, const QString &fileName, void *ptr, const SecureArray &passphrase, ConvertResult *result, const QString &provider) { - PrivateKey out; - ConvertResult r; - out = getKey, SecureArray>(provider, der, passphrase, &r); + PrivateKey out; + ConvertResult r; + out = getKey, SecureArray>(provider, der, passphrase, &r); - // error converting without passphrase? maybe a passphrase is needed - if(use_asker_fallback(r) && passphrase.isEmpty()) - { - SecureArray pass; - if(ask_passphrase(fileName, ptr, &pass)) - out = getKey, SecureArray>(provider, der, pass, &r); - } - if(result) - *result = r; - return out; + // error converting without passphrase? maybe a passphrase is needed + if (use_asker_fallback(r) && passphrase.isEmpty()) { + SecureArray pass; + if (ask_passphrase(fileName, ptr, &pass)) { + out = getKey, SecureArray>(provider, der, pass, &r); + } + } + if (result) { + *result = r; + } + return out; } static PrivateKey get_privatekey_pem(const QString &pem, const QString &fileName, void *ptr, const SecureArray &passphrase, ConvertResult *result, const QString &provider) { - PrivateKey out; - ConvertResult r; - out = getKey, QString>(provider, pem, passphrase, &r); + PrivateKey out; + ConvertResult r; + out = getKey, QString>(provider, pem, passphrase, &r); - // error converting without passphrase? maybe a passphrase is needed - if(use_asker_fallback(r) && passphrase.isEmpty()) - { - SecureArray pass; - if(ask_passphrase(fileName, ptr, &pass)) - out = getKey, QString>(provider, pem, pass, &r); - } - if(result) - *result = r; - return out; + // error converting without passphrase? maybe a passphrase is needed + if (use_asker_fallback(r) && passphrase.isEmpty()) { + SecureArray pass; + if (ask_passphrase(fileName, ptr, &pass)) { + out = getKey, QString>(provider, pem, pass, &r); + } + } + if (result) { + *result = r; + } + return out; } //---------------------------------------------------------------------------- // Global //---------------------------------------------------------------------------- // adapted from Botan -static const unsigned char pkcs_sha1[] = -{ - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, - 0x1A, 0x05, 0x00, 0x04, 0x14 +static const unsigned char pkcs_sha1[] = { + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, + 0x1A, 0x05, 0x00, 0x04, 0x14 }; -static const unsigned char pkcs_md5[] = -{ - 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 +static const unsigned char pkcs_md5[] = { + 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; -static const unsigned char pkcs_md2[] = -{ - 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, - 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 +static const unsigned char pkcs_md2[] = { + 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 }; -static const unsigned char pkcs_ripemd160[] = -{ - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, - 0x01, 0x05, 0x00, 0x04, 0x14 +static const unsigned char pkcs_ripemd160[] = { + 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, + 0x01, 0x05, 0x00, 0x04, 0x14 }; QByteArray get_hash_id(const QString &name) { - if(name == "sha1") - return QByteArray::fromRawData((const char *)pkcs_sha1, sizeof(pkcs_sha1)); - else if(name == "md5") - return QByteArray::fromRawData((const char *)pkcs_md5, sizeof(pkcs_md5)); - else if(name == "md2") - return QByteArray::fromRawData((const char *)pkcs_md2, sizeof(pkcs_md2)); - else if(name == "ripemd160") - return QByteArray::fromRawData((const char *)pkcs_ripemd160, sizeof(pkcs_ripemd160)); - else - return QByteArray(); + if (name == "sha1") { + return QByteArray::fromRawData((const char *)pkcs_sha1, sizeof(pkcs_sha1)); + } else if (name == "md5") { + return QByteArray::fromRawData((const char *)pkcs_md5, sizeof(pkcs_md5)); + } else if (name == "md2") { + return QByteArray::fromRawData((const char *)pkcs_md2, sizeof(pkcs_md2)); + } else if (name == "ripemd160") { + return QByteArray::fromRawData((const char *)pkcs_ripemd160, sizeof(pkcs_ripemd160)); + } else { + return QByteArray(); + } } QByteArray emsa3Encode(const QString &hashName, const QByteArray &digest, int size) { - QByteArray hash_id = get_hash_id(hashName); - if(hash_id.isEmpty()) - return QByteArray(); - - // logic adapted from Botan - int basesize = hash_id.size() + digest.size() + 2; - if(size == -1) - size = basesize + 1; // default to 1-byte pad - int padlen = size - basesize; - if(padlen < 1) - return QByteArray(); - - QByteArray out(size, (char)0xff); // pad with 0xff - out[0] = 0x01; - out[padlen + 1] = 0x00; - int at = padlen + 2; - memcpy(out.data() + at, hash_id.data(), hash_id.size()); - at += hash_id.size(); - memcpy(out.data() + at, digest.data(), digest.size()); - return out; + QByteArray hash_id = get_hash_id(hashName); + if (hash_id.isEmpty()) { + return QByteArray(); + } + + // logic adapted from Botan + int basesize = hash_id.size() + digest.size() + 2; + if (size == -1) { + size = basesize + 1; // default to 1-byte pad + } + int padlen = size - basesize; + if (padlen < 1) { + return QByteArray(); + } + + QByteArray out(size, (char)0xff); // pad with 0xff + out[0] = 0x01; + out[padlen + 1] = 0x00; + int at = padlen + 2; + memcpy(out.data() + at, hash_id.data(), hash_id.size()); + at += hash_id.size(); + memcpy(out.data() + at, digest.data(), digest.size()); + return out; } //---------------------------------------------------------------------------- // DLGroup //---------------------------------------------------------------------------- class DLGroup::Private { public: - BigInteger p, q, g; + BigInteger p, q, g; - Private(const BigInteger &p1, const BigInteger &q1, const BigInteger &g1) - :p(p1), q(q1), g(g1) - { - } + Private(const BigInteger &p1, const BigInteger &q1, const BigInteger &g1) + : p(p1), q(q1), g(g1) + { + } }; DLGroup::DLGroup() { - d = 0; + d = 0; } DLGroup::DLGroup(const BigInteger &p, const BigInteger &q, const BigInteger &g) { - d = new Private(p, q, g); + d = new Private(p, q, g); } DLGroup::DLGroup(const BigInteger &p, const BigInteger &g) { - d = new Private(p, 0, g); + d = new Private(p, 0, g); } DLGroup::DLGroup(const DLGroup &from) { - d = 0; - *this = from; + d = 0; + *this = from; } DLGroup::~DLGroup() { - delete d; + delete d; } -DLGroup & DLGroup::operator=(const DLGroup &from) +DLGroup &DLGroup::operator=(const DLGroup &from) { - delete d; - d = 0; + delete d; + d = 0; - if(from.d) - d = new Private(*from.d); + if (from.d) { + d = new Private(*from.d); + } - return *this; + return *this; } QList DLGroup::supportedGroupSets(const QString &provider) { - return getList(provider); + return getList(provider); } bool DLGroup::isNull() const { - return (d ? false: true); + return (d ? false : true); } BigInteger DLGroup::p() const { - Q_ASSERT(d); - return d->p; + Q_ASSERT(d); + return d->p; } BigInteger DLGroup::q() const { - Q_ASSERT(d); - return d->q; + Q_ASSERT(d); + return d->q; } BigInteger DLGroup::g() const { - Q_ASSERT(d); - return d->g; + Q_ASSERT(d); + return d->g; } //---------------------------------------------------------------------------- @@ -557,197 +576,211 @@ PKey::PKey() { - d = new Private; + d = new Private; } PKey::PKey(const QString &type, const QString &provider) -:Algorithm(type, provider) + : Algorithm(type, provider) { - d = new Private; + d = new Private; } PKey::PKey(const PKey &from) -:Algorithm(from) + : Algorithm(from) { - d = new Private; - *this = from; + d = new Private; + *this = from; } PKey::~PKey() { - delete d; + delete d; } -PKey & PKey::operator=(const PKey &from) +PKey &PKey::operator=(const PKey &from) { - Algorithm::operator=(from); - *d = *from.d; - return *this; + Algorithm::operator=(from); + *d = *from.d; + return *this; } void PKey::set(const PKey &k) { - *this = k; + *this = k; } void PKey::assignToPublic(PKey *dest) const { - dest->set(*this); + dest->set(*this); - // converting private to public - if(dest->isPrivate()) - static_cast(dest->context())->key()->convertToPublic(); + // converting private to public + if (dest->isPrivate()) { + static_cast(dest->context())->key()->convertToPublic(); + } } void PKey::assignToPrivate(PKey *dest) const { - dest->set(*this); + dest->set(*this); } QList PKey::supportedTypes(const QString &provider) { - return getList(provider); + return getList(provider); } QList PKey::supportedIOTypes(const QString &provider) { - return getList(provider); + return getList(provider); } bool PKey::isNull() const { - return (!context() ? true : false); + return (!context() ? true : false); } PKey::Type PKey::type() const { - if(isNull()) - return RSA; // some default so we don't explode - return static_cast(context())->key()->type(); + if (isNull()) { + return RSA; // some default so we don't explode + } + return static_cast(context())->key()->type(); } int PKey::bitSize() const { - return static_cast(context())->key()->bits(); + return static_cast(context())->key()->bits(); } bool PKey::isRSA() const { - return (type() == RSA); + return (type() == RSA); } bool PKey::isDSA() const { - return (type() == DSA); + return (type() == DSA); } bool PKey::isDH() const { - return (type() == DH); + return (type() == DH); } bool PKey::isPublic() const { - if(isNull()) - return false; - return !isPrivate(); + if (isNull()) { + return false; + } + return !isPrivate(); } bool PKey::isPrivate() const { - if(isNull()) - return false; - return static_cast(context())->key()->isPrivate(); + if (isNull()) { + return false; + } + return static_cast(context())->key()->isPrivate(); } bool PKey::canExport() const { - return static_cast(context())->key()->canExport(); + return static_cast(context())->key()->canExport(); } bool PKey::canKeyAgree() const { - return isDH(); + return isDH(); } PublicKey PKey::toPublicKey() const { - PublicKey k; - if(!isNull()) - assignToPublic(&k); - return k; + PublicKey k; + if (!isNull()) { + assignToPublic(&k); + } + return k; } PrivateKey PKey::toPrivateKey() const { - PrivateKey k; - if(!isNull() && isPrivate()) - assignToPrivate(&k); - return k; + PrivateKey k; + if (!isNull() && isPrivate()) { + assignToPrivate(&k); + } + return k; } RSAPublicKey PKey::toRSAPublicKey() const { - RSAPublicKey k; - if(!isNull() && isRSA()) - assignToPublic(&k); - return k; + RSAPublicKey k; + if (!isNull() && isRSA()) { + assignToPublic(&k); + } + return k; } RSAPrivateKey PKey::toRSAPrivateKey() const { - RSAPrivateKey k; - if(!isNull() && isRSA() && isPrivate()) - assignToPrivate(&k); - return k; + RSAPrivateKey k; + if (!isNull() && isRSA() && isPrivate()) { + assignToPrivate(&k); + } + return k; } DSAPublicKey PKey::toDSAPublicKey() const { - DSAPublicKey k; - if(!isNull() && isDSA()) - assignToPublic(&k); - return k; + DSAPublicKey k; + if (!isNull() && isDSA()) { + assignToPublic(&k); + } + return k; } DSAPrivateKey PKey::toDSAPrivateKey() const { - DSAPrivateKey k; - if(!isNull() && isDSA() && isPrivate()) - assignToPrivate(&k); - return k; + DSAPrivateKey k; + if (!isNull() && isDSA() && isPrivate()) { + assignToPrivate(&k); + } + return k; } DHPublicKey PKey::toDHPublicKey() const { - DHPublicKey k; - if(!isNull() && isDH()) - assignToPublic(&k); - return k; + DHPublicKey k; + if (!isNull() && isDH()) { + assignToPublic(&k); + } + return k; } DHPrivateKey PKey::toDHPrivateKey() const { - DHPrivateKey k; - if(!isNull() && isDH() && isPrivate()) - assignToPrivate(&k); - return k; + DHPrivateKey k; + if (!isNull() && isDH() && isPrivate()) { + assignToPrivate(&k); + } + return k; } bool PKey::operator==(const PKey &a) const { - if(isNull() || a.isNull() || type() != a.type()) - return false; + if (isNull() || a.isNull() || type() != a.type()) { + return false; + } - if(a.isPrivate()) - return (toPrivateKey().toDER() == a.toPrivateKey().toDER()); - else - return (toPublicKey().toDER() == a.toPublicKey().toDER()); + if (a.isPrivate()) { + return (toPrivateKey().toDER() == a.toPrivateKey().toDER()); + } else { + return (toPublicKey().toDER() == a.toPublicKey().toDER()); + } } bool PKey::operator!=(const PKey &a) const { - return !(*this == a); + return !(*this == a); } //---------------------------------------------------------------------------- @@ -758,194 +791,199 @@ } PublicKey::PublicKey(const QString &type, const QString &provider) -:PKey(type, provider) + : PKey(type, provider) { } PublicKey::PublicKey(const PrivateKey &k) { - set(k.toPublicKey()); + set(k.toPublicKey()); } PublicKey::PublicKey(const QString &fileName) { - *this = fromPEMFile(fileName, 0, QString()); + *this = fromPEMFile(fileName, 0, QString()); } PublicKey::PublicKey(const PublicKey &from) -:PKey(from) + : PKey(from) { } PublicKey::~PublicKey() { } -PublicKey & PublicKey::operator=(const PublicKey &from) +PublicKey &PublicKey::operator=(const PublicKey &from) { - PKey::operator=(from); - return *this; + PKey::operator=(from); + return *this; } RSAPublicKey PublicKey::toRSA() const { - return toRSAPublicKey(); + return toRSAPublicKey(); } DSAPublicKey PublicKey::toDSA() const { - return toDSAPublicKey(); + return toDSAPublicKey(); } DHPublicKey PublicKey::toDH() const { - return toDHPublicKey(); + return toDHPublicKey(); } bool PublicKey::canEncrypt() const { - return isRSA(); + return isRSA(); } bool PublicKey::canDecrypt() const { - return isRSA(); + return isRSA(); } bool PublicKey::canVerify() const { - return (isRSA() || isDSA()); + return (isRSA() || isDSA()); } int PublicKey::maximumEncryptSize(EncryptionAlgorithm alg) const { - const PKeyContext* ctx = qobject_cast(context()); - if (ctx) - return ctx->key()->maximumEncryptSize(alg); - else - return -1; + const PKeyContext *ctx = qobject_cast(context()); + if (ctx) { + return ctx->key()->maximumEncryptSize(alg); + } else { + return -1; + } } SecureArray PublicKey::encrypt(const SecureArray &a, EncryptionAlgorithm alg) { - PKeyContext* ctx = qobject_cast(context()); - if (ctx) - return ctx->key()->encrypt(a, alg); - else - return SecureArray(); + PKeyContext *ctx = qobject_cast(context()); + if (ctx) { + return ctx->key()->encrypt(a, alg); + } else { + return SecureArray(); + } } bool PublicKey::decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg) { - PKeyContext* ctx = qobject_cast(context()); - if (ctx) - return ctx->key()->decrypt(in, out, alg); - else - return false; + PKeyContext *ctx = qobject_cast(context()); + if (ctx) { + return ctx->key()->decrypt(in, out, alg); + } else { + return false; + } } void PublicKey::startVerify(SignatureAlgorithm alg, SignatureFormat format) { - if(isDSA() && format == DefaultFormat) - format = IEEE_1363; - PKeyContext* ctx = qobject_cast(context()); - if(ctx) - ctx->key()->startVerify(alg, format); + if (isDSA() && format == DefaultFormat) { + format = IEEE_1363; + } + PKeyContext *ctx = qobject_cast(context()); + if (ctx) { + ctx->key()->startVerify(alg, format); + } } void PublicKey::update(const MemoryRegion &a) { - PKeyContext* ctx = qobject_cast(context()); - if(ctx) { - ctx->key()->update(a); - } + PKeyContext *ctx = qobject_cast(context()); + if (ctx) { + ctx->key()->update(a); + } } bool PublicKey::validSignature(const QByteArray &sig) { - PKeyContext* ctx = qobject_cast(context()); - if(ctx) - return ctx->key()->endVerify(sig); - return false; + PKeyContext *ctx = qobject_cast(context()); + if (ctx) { + return ctx->key()->endVerify(sig); + } + return false; } bool PublicKey::verifyMessage(const MemoryRegion &a, const QByteArray &sig, SignatureAlgorithm alg, SignatureFormat format) { - startVerify(alg, format); - update(a); - return validSignature(sig); + startVerify(alg, format); + update(a); + return validSignature(sig); } QByteArray PublicKey::toDER() const { - QByteArray out; - const PKeyContext *cur = static_cast(context()); - Provider *p = providerForIOType(type(), cur); - if(!p) - return out; - if(cur->provider() == p) - { - out = cur->publicToDER(); - } - else - { - PKeyContext *pk = static_cast(getContext("pkey", p)); - if(pk && pk->importKey(cur->key())) - out = pk->publicToDER(); - delete pk; - } - return out; + QByteArray out; + const PKeyContext *cur = static_cast(context()); + Provider *p = providerForIOType(type(), cur); + if (!p) { + return out; + } + if (cur->provider() == p) { + out = cur->publicToDER(); + } else { + PKeyContext *pk = static_cast(getContext("pkey", p)); + if (pk && pk->importKey(cur->key())) { + out = pk->publicToDER(); + } + delete pk; + } + return out; } QString PublicKey::toPEM() const { - QString out; - const PKeyContext *cur = static_cast(context()); - if(!cur) - return out; - Provider *p = providerForIOType(type(), cur); - if(!p) - return out; - if(cur->provider() == p) - { - out = cur->publicToPEM(); - } - else - { - PKeyContext *pk = static_cast(getContext("pkey", p)); - if(pk && pk->importKey(cur->key())) - out = pk->publicToPEM(); - delete pk; - } - return out; + QString out; + const PKeyContext *cur = static_cast(context()); + if (!cur) { + return out; + } + Provider *p = providerForIOType(type(), cur); + if (!p) { + return out; + } + if (cur->provider() == p) { + out = cur->publicToPEM(); + } else { + PKeyContext *pk = static_cast(getContext("pkey", p)); + if (pk && pk->importKey(cur->key())) { + out = pk->publicToPEM(); + } + delete pk; + } + return out; } bool PublicKey::toPEMFile(const QString &fileName) const { - return stringToFile(fileName, toPEM()); + return stringToFile(fileName, toPEM()); } PublicKey PublicKey::fromDER(const QByteArray &a, ConvertResult *result, const QString &provider) { - return getKey, QByteArray>(provider, a, SecureArray(), result); + return getKey, QByteArray>(provider, a, SecureArray(), result); } PublicKey PublicKey::fromPEM(const QString &s, ConvertResult *result, const QString &provider) { - return getKey, QString>(provider, s, SecureArray(), result); + return getKey, QString>(provider, s, SecureArray(), result); } PublicKey PublicKey::fromPEMFile(const QString &fileName, ConvertResult *result, const QString &provider) { - QString pem; - if(!stringFromFile(fileName, &pem)) - { - if(result) - *result = ErrorFile; - return PublicKey(); - } - return fromPEM(pem, result, provider); + QString pem; + if (!stringFromFile(fileName, &pem)) { + if (result) { + *result = ErrorFile; + } + return PublicKey(); + } + return fromPEM(pem, result, provider); } //---------------------------------------------------------------------------- @@ -956,58 +994,58 @@ } PrivateKey::PrivateKey(const QString &type, const QString &provider) -:PKey(type, provider) + : PKey(type, provider) { } PrivateKey::PrivateKey(const QString &fileName, const SecureArray &passphrase) { - *this = fromPEMFile(fileName, passphrase, 0, QString()); + *this = fromPEMFile(fileName, passphrase, 0, QString()); } PrivateKey::PrivateKey(const PrivateKey &from) -:PKey(from) + : PKey(from) { } PrivateKey::~PrivateKey() { } -PrivateKey & PrivateKey::operator=(const PrivateKey &from) +PrivateKey &PrivateKey::operator=(const PrivateKey &from) { - PKey::operator=(from); - return *this; + PKey::operator=(from); + return *this; } RSAPrivateKey PrivateKey::toRSA() const { - return toRSAPrivateKey(); + return toRSAPrivateKey(); } DSAPrivateKey PrivateKey::toDSA() const { - return toDSAPrivateKey(); + return toDSAPrivateKey(); } DHPrivateKey PrivateKey::toDH() const { - return toDHPrivateKey(); + return toDHPrivateKey(); } bool PrivateKey::canDecrypt() const { - return isRSA(); + return isRSA(); } bool PrivateKey::canEncrypt() const { - return isRSA(); + return isRSA(); } bool PrivateKey::canSign() const { - return (isRSA() || isDSA()); + return (isRSA() || isDSA()); } int PrivateKey::maximumEncryptSize(EncryptionAlgorithm alg) const @@ -1017,343 +1055,334 @@ bool PrivateKey::decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg) { - return static_cast(context())->key()->decrypt(in, out, alg); + return static_cast(context())->key()->decrypt(in, out, alg); } SecureArray PrivateKey::encrypt(const SecureArray &a, EncryptionAlgorithm alg) { - return static_cast(context())->key()->encrypt(a, alg); + return static_cast(context())->key()->encrypt(a, alg); } void PrivateKey::startSign(SignatureAlgorithm alg, SignatureFormat format) { - if(isDSA() && format == DefaultFormat) - format = IEEE_1363; - static_cast(context())->key()->startSign(alg, format); + if (isDSA() && format == DefaultFormat) { + format = IEEE_1363; + } + static_cast(context())->key()->startSign(alg, format); } void PrivateKey::update(const MemoryRegion &a) { - static_cast(context())->key()->update(a); + static_cast(context())->key()->update(a); } QByteArray PrivateKey::signature() { - return static_cast(context())->key()->endSign(); + return static_cast(context())->key()->endSign(); } QByteArray PrivateKey::signMessage(const MemoryRegion &a, SignatureAlgorithm alg, SignatureFormat format) { - startSign(alg, format); - update(a); - return signature(); + startSign(alg, format); + update(a); + return signature(); } SymmetricKey PrivateKey::deriveKey(const PublicKey &theirs) { - const PKeyContext *theirContext = static_cast(theirs.context()); - return static_cast(context())->key()->deriveKey(*(theirContext->key())); + const PKeyContext *theirContext = static_cast(theirs.context()); + return static_cast(context())->key()->deriveKey(*(theirContext->key())); } QList PrivateKey::supportedPBEAlgorithms(const QString &provider) { - return getList(provider); + return getList(provider); } SecureArray PrivateKey::toDER(const SecureArray &passphrase, PBEAlgorithm pbe) const { - SecureArray out; - if(pbe == PBEDefault) - pbe = get_pbe_default(); - const PKeyContext *cur = static_cast(context()); - Provider *p = providerForPBE(pbe, type(), cur); - if(!p) - return out; - if(cur->provider() == p) - { - out = cur->privateToDER(passphrase, pbe); - } - else - { - PKeyContext *pk = static_cast(getContext("pkey", p)); - if(pk->importKey(cur->key())) - out = pk->privateToDER(passphrase, pbe); - delete pk; - } - return out; + SecureArray out; + if (pbe == PBEDefault) { + pbe = get_pbe_default(); + } + const PKeyContext *cur = static_cast(context()); + Provider *p = providerForPBE(pbe, type(), cur); + if (!p) { + return out; + } + if (cur->provider() == p) { + out = cur->privateToDER(passphrase, pbe); + } else { + PKeyContext *pk = static_cast(getContext("pkey", p)); + if (pk->importKey(cur->key())) { + out = pk->privateToDER(passphrase, pbe); + } + delete pk; + } + return out; } QString PrivateKey::toPEM(const SecureArray &passphrase, PBEAlgorithm pbe) const { - QString out; - if(pbe == PBEDefault) - pbe = get_pbe_default(); - const PKeyContext *cur = static_cast(context()); - Provider *p = providerForPBE(pbe, type(), cur); - if(!p) - return out; - if(cur->provider() == p) - { - out = cur->privateToPEM(passphrase, pbe); - } - else - { - PKeyContext *pk = static_cast(getContext("pkey", p)); - if(pk->importKey(cur->key())) - out = pk->privateToPEM(passphrase, pbe); - delete pk; - } - return out; + QString out; + if (pbe == PBEDefault) { + pbe = get_pbe_default(); + } + const PKeyContext *cur = static_cast(context()); + Provider *p = providerForPBE(pbe, type(), cur); + if (!p) { + return out; + } + if (cur->provider() == p) { + out = cur->privateToPEM(passphrase, pbe); + } else { + PKeyContext *pk = static_cast(getContext("pkey", p)); + if (pk->importKey(cur->key())) { + out = pk->privateToPEM(passphrase, pbe); + } + delete pk; + } + return out; } bool PrivateKey::toPEMFile(const QString &fileName, const SecureArray &passphrase, PBEAlgorithm pbe) const { - return stringToFile(fileName, toPEM(passphrase, pbe)); + return stringToFile(fileName, toPEM(passphrase, pbe)); } PrivateKey PrivateKey::fromDER(const SecureArray &a, const SecureArray &passphrase, ConvertResult *result, const QString &provider) { - return get_privatekey_der(a, QString(), (void *)&a, passphrase, result, provider); + return get_privatekey_der(a, QString(), (void *)&a, passphrase, result, provider); } PrivateKey PrivateKey::fromPEM(const QString &s, const SecureArray &passphrase, ConvertResult *result, const QString &provider) { - return get_privatekey_pem(s, QString(), (void *)&s, passphrase, result, provider); + return get_privatekey_pem(s, QString(), (void *)&s, passphrase, result, provider); } PrivateKey PrivateKey::fromPEMFile(const QString &fileName, const SecureArray &passphrase, ConvertResult *result, const QString &provider) { - QString pem; - if(!stringFromFile(fileName, &pem)) - { - if(result) - *result = ErrorFile; - return PrivateKey(); - } - return get_privatekey_pem(pem, fileName, 0, passphrase, result, provider); + QString pem; + if (!stringFromFile(fileName, &pem)) { + if (result) { + *result = ErrorFile; + } + return PrivateKey(); + } + return get_privatekey_pem(pem, fileName, 0, passphrase, result, provider); } //---------------------------------------------------------------------------- // KeyGenerator //---------------------------------------------------------------------------- class KeyGenerator::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - KeyGenerator *parent; - bool blocking, wasBlocking; - PrivateKey key; - DLGroup group; - - PKeyBase *k; - PKeyContext *dest; - DLGroupContext *dc; - - Private(KeyGenerator *_parent) : QObject(_parent), parent(_parent) - { - k = 0; - dest = 0; - dc = 0; - } - - ~Private() - { - delete k; - delete dest; - delete dc; - } + KeyGenerator *parent; + bool blocking, wasBlocking; + PrivateKey key; + DLGroup group; + + PKeyBase *k; + PKeyContext *dest; + DLGroupContext *dc; + + Private(KeyGenerator *_parent) : QObject(_parent), parent(_parent) + { + k = 0; + dest = 0; + dc = 0; + } + + ~Private() + { + delete k; + delete dest; + delete dc; + } public slots: - void done() - { - if(!k->isNull()) - { - if(!wasBlocking) - { - k->setParent(0); - k->moveToThread(0); - } - dest->setKey(k); - k = 0; - - key.change(dest); - dest = 0; - } - else - { - delete k; - k = 0; - delete dest; - dest = 0; - } - - if(!wasBlocking) - emit parent->finished(); - } - - void done_group() - { - if(!dc->isNull()) - { - BigInteger p, q, g; - dc->getResult(&p, &q, &g); - group = DLGroup(p, q, g); - } - delete dc; - dc = 0; - - if(!wasBlocking) - emit parent->finished(); - } + void done() + { + if (!k->isNull()) { + if (!wasBlocking) { + k->setParent(0); + k->moveToThread(0); + } + dest->setKey(k); + k = 0; + + key.change(dest); + dest = 0; + } else { + delete k; + k = 0; + delete dest; + dest = 0; + } + + if (!wasBlocking) { + emit parent->finished(); + } + } + + void done_group() + { + if (!dc->isNull()) { + BigInteger p, q, g; + dc->getResult(&p, &q, &g); + group = DLGroup(p, q, g); + } + delete dc; + dc = 0; + + if (!wasBlocking) { + emit parent->finished(); + } + } }; KeyGenerator::KeyGenerator(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); - d->blocking = true; + d = new Private(this); + d->blocking = true; } KeyGenerator::~KeyGenerator() { - delete d; + delete d; } bool KeyGenerator::blockingEnabled() const { - return d->blocking; + return d->blocking; } void KeyGenerator::setBlockingEnabled(bool b) { - d->blocking = b; + d->blocking = b; } bool KeyGenerator::isBusy() const { - return (d->k ? true: false); + return (d->k ? true : false); } PrivateKey KeyGenerator::createRSA(int bits, int exp, const QString &provider) { - if(isBusy()) - return PrivateKey(); + if (isBusy()) { + return PrivateKey(); + } - d->key = PrivateKey(); - d->wasBlocking = d->blocking; - d->k = static_cast(getContext("rsa", provider)); - if (!d->k) - return PrivateKey(); - d->dest = static_cast(getContext("pkey", d->k->provider())); + d->key = PrivateKey(); + d->wasBlocking = d->blocking; + d->k = static_cast(getContext("rsa", provider)); + if (!d->k) { + return PrivateKey(); + } + d->dest = static_cast(getContext("pkey", d->k->provider())); - if(!d->blocking) - { - d->k->moveToThread(thread()); - d->k->setParent(d); - connect(d->k, SIGNAL(finished()), d, SLOT(done())); - static_cast(d->k)->createPrivate(bits, exp, false); - } - else - { - static_cast(d->k)->createPrivate(bits, exp, true); - d->done(); - } + if (!d->blocking) { + d->k->moveToThread(thread()); + d->k->setParent(d); + connect(d->k, SIGNAL(finished()), d, SLOT(done())); + static_cast(d->k)->createPrivate(bits, exp, false); + } else { + static_cast(d->k)->createPrivate(bits, exp, true); + d->done(); + } - return d->key; + return d->key; } PrivateKey KeyGenerator::createDSA(const DLGroup &domain, const QString &provider) { - if(isBusy()) - return PrivateKey(); + if (isBusy()) { + return PrivateKey(); + } - d->key = PrivateKey(); - d->wasBlocking = d->blocking; - d->k = static_cast(getContext("dsa", provider)); - d->dest = static_cast(getContext("pkey", d->k->provider())); + d->key = PrivateKey(); + d->wasBlocking = d->blocking; + d->k = static_cast(getContext("dsa", provider)); + d->dest = static_cast(getContext("pkey", d->k->provider())); - if(!d->blocking) - { - d->k->moveToThread(thread()); - d->k->setParent(d); - connect(d->k, SIGNAL(finished()), d, SLOT(done())); - static_cast(d->k)->createPrivate(domain, false); - } - else - { - static_cast(d->k)->createPrivate(domain, true); - d->done(); - } + if (!d->blocking) { + d->k->moveToThread(thread()); + d->k->setParent(d); + connect(d->k, SIGNAL(finished()), d, SLOT(done())); + static_cast(d->k)->createPrivate(domain, false); + } else { + static_cast(d->k)->createPrivate(domain, true); + d->done(); + } - return d->key; + return d->key; } PrivateKey KeyGenerator::createDH(const DLGroup &domain, const QString &provider) { - if(isBusy()) - return PrivateKey(); + if (isBusy()) { + return PrivateKey(); + } - d->key = PrivateKey(); - d->wasBlocking = d->blocking; - d->k = static_cast(getContext("dh", provider)); - d->dest = static_cast(getContext("pkey", d->k->provider())); + d->key = PrivateKey(); + d->wasBlocking = d->blocking; + d->k = static_cast(getContext("dh", provider)); + d->dest = static_cast(getContext("pkey", d->k->provider())); - if(!d->blocking) - { - d->k->moveToThread(thread()); - d->k->setParent(d); - connect(d->k, SIGNAL(finished()), d, SLOT(done())); - static_cast(d->k)->createPrivate(domain, false); - } - else - { - static_cast(d->k)->createPrivate(domain, true); - d->done(); - } + if (!d->blocking) { + d->k->moveToThread(thread()); + d->k->setParent(d); + connect(d->k, SIGNAL(finished()), d, SLOT(done())); + static_cast(d->k)->createPrivate(domain, false); + } else { + static_cast(d->k)->createPrivate(domain, true); + d->done(); + } - return d->key; + return d->key; } PrivateKey KeyGenerator::key() const { - return d->key; + return d->key; } DLGroup KeyGenerator::createDLGroup(QCA::DLGroupSet set, const QString &provider) { - if(isBusy()) - return DLGroup(); + if (isBusy()) { + return DLGroup(); + } - Provider *p; - if(!provider.isEmpty()) - p = providerForName(provider); - else - p = providerForGroupSet(set); + Provider *p; + if (!provider.isEmpty()) { + p = providerForName(provider); + } else { + p = providerForGroupSet(set); + } - d->dc = static_cast(getContext("dlgroup", p)); - d->group = DLGroup(); + d->dc = static_cast(getContext("dlgroup", p)); + d->group = DLGroup(); - if (d->dc) - { - d->wasBlocking = d->blocking; - if(!d->blocking) - { - connect(d->dc, SIGNAL(finished()), d, SLOT(done_group())); - d->dc->fetchGroup(set, false); - } - else - { - d->dc->fetchGroup(set, true); - d->done_group(); - } - } + if (d->dc) { + d->wasBlocking = d->blocking; + if (!d->blocking) { + connect(d->dc, SIGNAL(finished()), d, SLOT(done_group())); + d->dc->fetchGroup(set, false); + } else { + d->dc->fetchGroup(set, true); + d->done_group(); + } + } - return d->group; + return d->group; } DLGroup KeyGenerator::dlGroup() const { - return d->group; + return d->group; } //---------------------------------------------------------------------------- @@ -1365,26 +1394,26 @@ RSAPublicKey::RSAPublicKey(const BigInteger &n, const BigInteger &e, const QString &provider) { - RSAContext *k = static_cast(getContext("rsa", provider)); - k->createPublic(n, e); - PKeyContext *c = static_cast(getContext("pkey", k->provider())); - c->setKey(k); - change(c); + RSAContext *k = static_cast(getContext("rsa", provider)); + k->createPublic(n, e); + PKeyContext *c = static_cast(getContext("pkey", k->provider())); + c->setKey(k); + change(c); } RSAPublicKey::RSAPublicKey(const RSAPrivateKey &k) -:PublicKey(k) + : PublicKey(k) { } BigInteger RSAPublicKey::n() const { - return static_cast(static_cast(context())->key())->n(); + return static_cast(static_cast(context())->key())->n(); } BigInteger RSAPublicKey::e() const { - return static_cast(static_cast(context())->key())->e(); + return static_cast(static_cast(context())->key())->e(); } //---------------------------------------------------------------------------- @@ -1396,36 +1425,36 @@ RSAPrivateKey::RSAPrivateKey(const BigInteger &n, const BigInteger &e, const BigInteger &p, const BigInteger &q, const BigInteger &d, const QString &provider) { - RSAContext *k = static_cast(getContext("rsa", provider)); - k->createPrivate(n, e, p, q, d); - PKeyContext *c = static_cast(getContext("pkey", k->provider())); - c->setKey(k); - change(c); + RSAContext *k = static_cast(getContext("rsa", provider)); + k->createPrivate(n, e, p, q, d); + PKeyContext *c = static_cast(getContext("pkey", k->provider())); + c->setKey(k); + change(c); } BigInteger RSAPrivateKey::n() const { - return static_cast(static_cast(context())->key())->n(); + return static_cast(static_cast(context())->key())->n(); } BigInteger RSAPrivateKey::e() const { - return static_cast(static_cast(context())->key())->e(); + return static_cast(static_cast(context())->key())->e(); } BigInteger RSAPrivateKey::p() const { - return static_cast(static_cast(context())->key())->p(); + return static_cast(static_cast(context())->key())->p(); } BigInteger RSAPrivateKey::q() const { - return static_cast(static_cast(context())->key())->q(); + return static_cast(static_cast(context())->key())->q(); } BigInteger RSAPrivateKey::d() const { - return static_cast(static_cast(context())->key())->d(); + return static_cast(static_cast(context())->key())->d(); } //---------------------------------------------------------------------------- @@ -1437,26 +1466,26 @@ DSAPublicKey::DSAPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider) { - DSAContext *k = static_cast(getContext("dsa", provider)); - k->createPublic(domain, y); - PKeyContext *c = static_cast(getContext("pkey", k->provider())); - c->setKey(k); - change(c); + DSAContext *k = static_cast(getContext("dsa", provider)); + k->createPublic(domain, y); + PKeyContext *c = static_cast(getContext("pkey", k->provider())); + c->setKey(k); + change(c); } DSAPublicKey::DSAPublicKey(const DSAPrivateKey &k) -:PublicKey(k) + : PublicKey(k) { } DLGroup DSAPublicKey::domain() const { - return static_cast(static_cast(context())->key())->domain(); + return static_cast(static_cast(context())->key())->domain(); } BigInteger DSAPublicKey::y() const { - return static_cast(static_cast(context())->key())->y(); + return static_cast(static_cast(context())->key())->y(); } //---------------------------------------------------------------------------- @@ -1468,26 +1497,26 @@ DSAPrivateKey::DSAPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider) { - DSAContext *k = static_cast(getContext("dsa", provider)); - k->createPrivate(domain, y, x); - PKeyContext *c = static_cast(getContext("pkey", k->provider())); - c->setKey(k); - change(c); + DSAContext *k = static_cast(getContext("dsa", provider)); + k->createPrivate(domain, y, x); + PKeyContext *c = static_cast(getContext("pkey", k->provider())); + c->setKey(k); + change(c); } DLGroup DSAPrivateKey::domain() const { - return static_cast(static_cast(context())->key())->domain(); + return static_cast(static_cast(context())->key())->domain(); } BigInteger DSAPrivateKey::y() const { - return static_cast(static_cast(context())->key())->y(); + return static_cast(static_cast(context())->key())->y(); } BigInteger DSAPrivateKey::x() const { - return static_cast(static_cast(context())->key())->x(); + return static_cast(static_cast(context())->key())->x(); } //---------------------------------------------------------------------------- @@ -1499,26 +1528,26 @@ DHPublicKey::DHPublicKey(const DLGroup &domain, const BigInteger &y, const QString &provider) { - DHContext *k = static_cast(getContext("dh", provider)); - k->createPublic(domain, y); - PKeyContext *c = static_cast(getContext("pkey", k->provider())); - c->setKey(k); - change(c); + DHContext *k = static_cast(getContext("dh", provider)); + k->createPublic(domain, y); + PKeyContext *c = static_cast(getContext("pkey", k->provider())); + c->setKey(k); + change(c); } DHPublicKey::DHPublicKey(const DHPrivateKey &k) -:PublicKey(k) + : PublicKey(k) { } DLGroup DHPublicKey::domain() const { - return static_cast(static_cast(context())->key())->domain(); + return static_cast(static_cast(context())->key())->domain(); } BigInteger DHPublicKey::y() const { - return static_cast(static_cast(context())->key())->y(); + return static_cast(static_cast(context())->key())->y(); } //---------------------------------------------------------------------------- @@ -1530,26 +1559,26 @@ DHPrivateKey::DHPrivateKey(const DLGroup &domain, const BigInteger &y, const BigInteger &x, const QString &provider) { - DHContext *k = static_cast(getContext("dh", provider)); - k->createPrivate(domain, y, x); - PKeyContext *c = static_cast(getContext("pkey", k->provider())); - c->setKey(k); - change(c); + DHContext *k = static_cast(getContext("dh", provider)); + k->createPrivate(domain, y, x); + PKeyContext *c = static_cast(getContext("pkey", k->provider())); + c->setKey(k); + change(c); } DLGroup DHPrivateKey::domain() const { - return static_cast(static_cast(context())->key())->domain(); + return static_cast(static_cast(context())->key())->domain(); } BigInteger DHPrivateKey::y() const { - return static_cast(static_cast(context())->key())->y(); + return static_cast(static_cast(context())->key())->y(); } BigInteger DHPrivateKey::x() const { - return static_cast(static_cast(context())->key())->x(); + return static_cast(static_cast(context())->key())->x(); } } diff --git a/src/qca_safeobj.h b/src/qca_safeobj.h --- a/src/qca_safeobj.h +++ b/src/qca_safeobj.h @@ -27,51 +27,62 @@ #include #include -namespace QCA { +namespace QCA +{ // This function performs the following steps: // obj->disconnect(owner); // to prevent future signals to owner // obj->setParent(0); // to prevent delete if parent is deleted // obj->deleteLater(); // now we can forget about the object inline void releaseAndDeleteLater(QObject *owner, QObject *obj) { - obj->disconnect(owner); - obj->setParent(0); - obj->deleteLater(); + obj->disconnect(owner); + obj->setParent(0); + obj->deleteLater(); } - - class SafeSocketNotifier : public QObject { - Q_OBJECT + Q_OBJECT public: - SafeSocketNotifier(int socket, QSocketNotifier::Type type, - QObject *parent = 0) : - QObject(parent) - { - sn = new QSocketNotifier(socket, type, this); - connect(sn, SIGNAL(activated(int)), SIGNAL(activated(int))); - } + SafeSocketNotifier(int socket, QSocketNotifier::Type type, + QObject *parent = 0) : + QObject(parent) + { + sn = new QSocketNotifier(socket, type, this); + connect(sn, SIGNAL(activated(int)), SIGNAL(activated(int))); + } - ~SafeSocketNotifier() - { - sn->setEnabled(false); - releaseAndDeleteLater(this, sn); - } + ~SafeSocketNotifier() + { + sn->setEnabled(false); + releaseAndDeleteLater(this, sn); + } - bool isEnabled() const { return sn->isEnabled(); } - int socket() const { return sn->socket(); } - QSocketNotifier::Type type() const { return sn->type(); } + bool isEnabled() const + { + return sn->isEnabled(); + } + int socket() const + { + return sn->socket(); + } + QSocketNotifier::Type type() const + { + return sn->type(); + } public slots: - void setEnabled(bool enable) { sn->setEnabled(enable); } + void setEnabled(bool enable) + { + sn->setEnabled(enable); + } signals: - void activated(int socket); + void activated(int socket); private: - QSocketNotifier *sn; + QSocketNotifier *sn; }; } diff --git a/src/qca_safetimer.cpp b/src/qca_safetimer.cpp --- a/src/qca_safetimer.cpp +++ b/src/qca_safetimer.cpp @@ -35,210 +35,202 @@ class SafeTimer::Private : public QObject { - Q_OBJECT - friend class SafeTimer; + Q_OBJECT + friend class SafeTimer; public: - Private(QObject *parent = 0); + Private(QObject *parent = 0); - int timerId; - int fixerTimerId; - bool isSingleShot; - int interval; - bool isActive; - QElapsedTimer elapsedTimer; + int timerId; + int fixerTimerId; + bool isSingleShot; + int interval; + bool isActive; + QElapsedTimer elapsedTimer; public slots: - void fixTimer(); + void fixTimer(); signals: - void needFix(); + void needFix(); protected: - bool event(QEvent *event); - void timerEvent(QTimerEvent *event); + bool event(QEvent *event); + void timerEvent(QTimerEvent *event); }; SafeTimer::Private::Private(QObject *parent) - : QObject(parent) - , timerId(0) - , fixerTimerId(0) - , isSingleShot(false) - , interval(0) - , isActive(false) - , elapsedTimer(QElapsedTimer()) + : QObject(parent) + , timerId(0) + , fixerTimerId(0) + , isSingleShot(false) + , interval(0) + , isActive(false) + , elapsedTimer(QElapsedTimer()) { - connect(this, SIGNAL(needFix()), SLOT(fixTimer()), Qt::QueuedConnection); + connect(this, SIGNAL(needFix()), SLOT(fixTimer()), Qt::QueuedConnection); } void SafeTimer::Private::fixTimer() { - // Start special timer to align ressurected old timer - int msec = qMax(0, interval - static_cast(elapsedTimer.elapsed())); + // Start special timer to align ressurected old timer + int msec = qMax(0, interval - static_cast(elapsedTimer.elapsed())); - fixerTimerId = startTimer(msec); + fixerTimerId = startTimer(msec); #ifdef SAFETIMER_DEBUG - qDebug() << "START FIXTIMER: id =" << fixerTimerId << ", thread =" << thread() << ", interval =" << msec << parent(); + qDebug() << "START FIXTIMER: id =" << fixerTimerId << ", thread =" << thread() << ", interval =" << msec << parent(); #endif } bool SafeTimer::Private::event(QEvent *event) { - if (event->type() == QEvent::ThreadChange && fixerTimerId /* timer is actived */) - { - // Timer dies when an object changes owner thread. This trick - // used to ressurect old timer in the new thread. - // Signal is emited in the old thread but will be gotten in the new one. + if (event->type() == QEvent::ThreadChange && fixerTimerId /* timer is actived */) { + // Timer dies when an object changes owner thread. This trick + // used to ressurect old timer in the new thread. + // Signal is emited in the old thread but will be gotten in the new one. #ifdef SAFETIMER_DEBUG - qDebug() << "STOP FIXTIMER ON CHANGE THREAD: id =" << fixerTimerId << ", thread =" << thread() << parent(); + qDebug() << "STOP FIXTIMER ON CHANGE THREAD: id =" << fixerTimerId << ", thread =" << thread() << parent(); #endif - killTimer(fixerTimerId); - fixerTimerId = 0; - emit needFix(); - } + killTimer(fixerTimerId); + fixerTimerId = 0; + emit needFix(); + } - return QObject::event(event); + return QObject::event(event); } void SafeTimer::Private::timerEvent(QTimerEvent *event) { - if (event->timerId() == fixerTimerId) - { + if (event->timerId() == fixerTimerId) { #ifdef SAFETIMER_DEBUG - qDebug() << "STOP FIXTIMER ON TIMEOUT: id =" << fixerTimerId << ", thread =" << thread() << parent(); + qDebug() << "STOP FIXTIMER ON TIMEOUT: id =" << fixerTimerId << ", thread =" << thread() << parent(); #endif - killTimer(fixerTimerId); - fixerTimerId = 0; - - SafeTimer *safeTimer = qobject_cast(parent()); - // Emulate timeout signal of not yet ressurected timer - emit safeTimer->timeout(); - // Ressurect timer here if not a singleshot - if (!isSingleShot) - safeTimer->start(); - else - isActive = false; - } - else - { + killTimer(fixerTimerId); + fixerTimerId = 0; + + SafeTimer *safeTimer = qobject_cast(parent()); + // Emulate timeout signal of not yet ressurected timer + emit safeTimer->timeout(); + // Ressurect timer here if not a singleshot + if (!isSingleShot) { + safeTimer->start(); + } else { + isActive = false; + } + } else { #ifdef SAFETIMER_DEBUG - qDebug() << "BAD PRIVATE TIME EVENT: id =" << timerId << ", thread =" << thread() << this << ", badId =" << event->timerId() << parent(); + qDebug() << "BAD PRIVATE TIME EVENT: id =" << timerId << ", thread =" << thread() << this << ", badId =" << event->timerId() << parent(); #endif - } + } } SafeTimer::SafeTimer(QObject *parent) - : QObject() - , d(new Private()) + : QObject() + , d(new Private()) { - // It must be done here. Initialization list can't be used. - // Need to have proper class name. Look at TimerFixer::hook. - setParent(parent); - d->setParent(this); + // It must be done here. Initialization list can't be used. + // Need to have proper class name. Look at TimerFixer::hook. + setParent(parent); + d->setParent(this); } SafeTimer::~SafeTimer() { } int SafeTimer::interval() const { - return d->interval; + return d->interval; } bool SafeTimer::isActive() const { - return d->isActive; + return d->isActive; } bool SafeTimer::isSingleShot() const { - return d->isSingleShot; + return d->isSingleShot; } void SafeTimer::setInterval(int msec) { - d->interval = msec; + d->interval = msec; } void SafeTimer::setSingleShot(bool singleShot) { - d->isSingleShot = singleShot; + d->isSingleShot = singleShot; } void SafeTimer::start(int msec) { - d->interval = msec; - start(); + d->interval = msec; + start(); } void SafeTimer::start() { - stop(); + stop(); - d->elapsedTimer.start(); - d->timerId = QObject::startTimer(d->interval); - d->isActive = d->timerId > 0; + d->elapsedTimer.start(); + d->timerId = QObject::startTimer(d->interval); + d->isActive = d->timerId > 0; #ifdef SAFETIMER_DEBUG - qDebug() << "START TIMER: id =" << d->timerId << ", thread =" << thread() << ", interval =" << d->interval << this; + qDebug() << "START TIMER: id =" << d->timerId << ", thread =" << thread() << ", interval =" << d->interval << this; #endif } void SafeTimer::stop() { - if (d->timerId) - { - QObject::killTimer(d->timerId); + if (d->timerId) { + QObject::killTimer(d->timerId); #ifdef SAFETIMER_DEBUG - qDebug() << "STOP TIMER: id =" << d->timerId << ", thread =" << thread() << this; + qDebug() << "STOP TIMER: id =" << d->timerId << ", thread =" << thread() << this; #endif - d->timerId = 0; - } + d->timerId = 0; + } - if (d->fixerTimerId) - { + if (d->fixerTimerId) { #ifdef SAFETIMER_DEBUG - qDebug() << "STOP FIXER TIMER: id =" << d->fixerTimerId << ", thread =" << thread() << this; + qDebug() << "STOP FIXER TIMER: id =" << d->fixerTimerId << ", thread =" << thread() << this; #endif - d->killTimer(d->fixerTimerId); - d->fixerTimerId = 0; - } - d->isActive = false; + d->killTimer(d->fixerTimerId); + d->fixerTimerId = 0; + } + d->isActive = false; } bool SafeTimer::event(QEvent *event) { - if (event->type() == QEvent::ThreadChange && d->timerId /* timer is actived */) - { - // Timer dies when an object changes owner thread. This trick - // used to ressurect old timer in the new thread. - // Signal is emited in the old thread but will be gotten in the new one. + if (event->type() == QEvent::ThreadChange && d->timerId /* timer is actived */) { + // Timer dies when an object changes owner thread. This trick + // used to ressurect old timer in the new thread. + // Signal is emited in the old thread but will be gotten in the new one. #ifdef SAFETIMER_DEBUG - qDebug() << "CHANGE THREAD: id =" << d->timerId << ", thread =" << thread() << this; + qDebug() << "CHANGE THREAD: id =" << d->timerId << ", thread =" << thread() << this; #endif - killTimer(d->timerId); - d->timerId = 0; - emit d->needFix(); - } + killTimer(d->timerId); + d->timerId = 0; + emit d->needFix(); + } - return QObject::event(event); + return QObject::event(event); } void SafeTimer::timerEvent(QTimerEvent *event) { - if (event->timerId() == d->timerId) - { - if (d->isSingleShot) - stop(); - emit timeout(); - } - else - { + if (event->timerId() == d->timerId) { + if (d->isSingleShot) { + stop(); + } + emit timeout(); + } else { #ifdef SAFETIMER_DEBUG - qDebug() << "BAD TIME EVENT: id =" << d->timerId << ", thread =" << thread() << this << ", badId =" << event->timerId() << this; + qDebug() << "BAD TIME EVENT: id =" << d->timerId << ", thread =" << thread() << this << ", badId =" << event->timerId() << this; #endif - } + } } } // end namespace QCA diff --git a/src/qca_securelayer.cpp b/src/qca_securelayer.cpp --- a/src/qca_securelayer.cpp +++ b/src/qca_securelayer.cpp @@ -30,103 +30,101 @@ #include #endif -namespace QCA { +namespace QCA +{ Provider::Context *getContext(const QString &type, const QString &provider); -enum ResetMode -{ - ResetSession = 0, - ResetSessionAndData = 1, - ResetAll = 2 +enum ResetMode { + ResetSession = 0, + ResetSessionAndData = 1, + ResetAll = 2 }; //---------------------------------------------------------------------------- // LayerTracker //---------------------------------------------------------------------------- class LayerTracker { private: - struct Item - { - int plain; - qint64 encoded; - }; + struct Item { + int plain; + qint64 encoded; + }; - int p; - QList list; + int p; + QList list; public: - LayerTracker() - { - p = 0; - } - - void reset() - { - p = 0; - list.clear(); - } - - void addPlain(int plain) - { - p += plain; - } - - void specifyEncoded(int encoded, int plain) - { - // can't specify more bytes than we have - if(plain > p) - plain = p; - p -= plain; - Item i; - i.plain = plain; - i.encoded = encoded; - list += i; - } - - int finished(qint64 encoded) - { - int plain = 0; - for(QList::Iterator it = list.begin(); it != list.end();) - { - Item &i = *it; - - // not enough? - if(encoded < i.encoded) - { - i.encoded -= encoded; - break; - } - - encoded -= i.encoded; - plain += i.plain; - it = list.erase(it); - } - return plain; - } + LayerTracker() + { + p = 0; + } + + void reset() + { + p = 0; + list.clear(); + } + + void addPlain(int plain) + { + p += plain; + } + + void specifyEncoded(int encoded, int plain) + { + // can't specify more bytes than we have + if (plain > p) { + plain = p; + } + p -= plain; + Item i; + i.plain = plain; + i.encoded = encoded; + list += i; + } + + int finished(qint64 encoded) + { + int plain = 0; + for (QList::Iterator it = list.begin(); it != list.end();) { + Item &i = *it; + + // not enough? + if (encoded < i.encoded) { + i.encoded -= encoded; + break; + } + + encoded -= i.encoded; + plain += i.plain; + it = list.erase(it); + } + return plain; + } }; //---------------------------------------------------------------------------- // SecureLayer //---------------------------------------------------------------------------- SecureLayer::SecureLayer(QObject *parent) -:QObject(parent) + : QObject(parent) { } bool SecureLayer::isClosable() const { - return false; + return false; } void SecureLayer::close() { } QByteArray SecureLayer::readUnprocessed() { - return QByteArray(); + return QByteArray(); } //---------------------------------------------------------------------------- @@ -137,1093 +135,1062 @@ } TLSSession::TLSSession(const TLSSession &from) -:Algorithm(from) + : Algorithm(from) { } TLSSession::~TLSSession() { } -TLSSession & TLSSession::operator=(const TLSSession &from) +TLSSession &TLSSession::operator=(const TLSSession &from) { - Algorithm::operator=(from); - return *this; + Algorithm::operator=(from); + return *this; } bool TLSSession::isNull() const { - return (!context() ? true : false); + return (!context() ? true : false); } //---------------------------------------------------------------------------- // TLS //---------------------------------------------------------------------------- class TLS::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - enum - { - OpStart, - OpUpdate - }; - - enum State - { - Inactive, - Initializing, - Handshaking, - Connected, - Closing - }; - - class Action - { - public: - enum Type - { - ReadyRead, - ReadyReadOutgoing, - Handshaken, - Close, - CheckPeerCertificate, - CertificateRequested, - HostNameReceived - }; - - int type; - - Action(int _type) : type(_type) - { - } - }; - - TLS *q; - TLSContext *c; - TLS::Mode mode; - - // signal connected flags - bool connect_hostNameReceived; - bool connect_certificateRequested; - bool connect_peerCertificateAvailable; - bool connect_handshaken; - - // persistent settings (survives ResetSessionAndData) - CertificateChain localCert; - PrivateKey localKey; - CertificateCollection trusted; - bool con_ssfMode; - int con_minSSF, con_maxSSF; - QStringList con_cipherSuites; - bool tryCompress; - int packet_mtu; - QList issuerList; - TLSSession session; - - // session - State state; - bool blocked; - bool server; - QString host; - TLSContext::SessionInfo sessionInfo; - SafeTimer actionTrigger; - int op; - QList actionQueue; - bool need_update; - bool maybe_input; - bool emitted_hostNameReceived; - bool emitted_certificateRequested; - bool emitted_peerCertificateAvailable; - - // data (survives ResetSession) - CertificateChain peerCert; - Validity peerValidity; - bool hostMismatch; - Error errorCode; - - // stream i/o - QByteArray in, out; - QByteArray to_net, from_net; - QByteArray unprocessed; - int out_pending; - int to_net_encoded; - LayerTracker layer; - - // datagram i/o - QList packet_in, packet_out; - QList packet_to_net, packet_from_net; - int packet_out_pending; // packet count - QList packet_to_net_encoded; - - Private(TLS *_q, TLS::Mode _mode) : QObject(_q), q(_q), mode(_mode), actionTrigger(this) - { - // c is 0 during initial reset, so we don't redundantly reset it - c = 0; - connect_hostNameReceived = false; - connect_certificateRequested = false; - connect_peerCertificateAvailable = false; - connect_handshaken = false; - server = false; - - connect(&actionTrigger, SIGNAL(timeout()), SLOT(doNextAction())); - actionTrigger.setSingleShot(true); - - reset(ResetAll); - - c = static_cast(q->context()); - - // parent the context to us, so that moveToThread works - c->setParent(this); - - connect(c, SIGNAL(resultsReady()), SLOT(tls_resultsReady())); - connect(c, SIGNAL(dtlsTimeout()), SLOT(tls_dtlsTimeout())); - } - - ~Private() - { - // context is owned by Algorithm, unparent so we don't double-delete - c->setParent(0); - } - - void reset(ResetMode mode) - { - if(c) - c->reset(); - - // if we reset while in client mode, then clear this list - // (it should only persist when used for server mode) - if(!server) - issuerList.clear(); - - state = Inactive; - blocked = false; - server = false; - host = QString(); - sessionInfo = TLSContext::SessionInfo(); - actionTrigger.stop(); - op = -1; - actionQueue.clear(); - need_update = false; - maybe_input = false; - emitted_hostNameReceived = false; - emitted_certificateRequested = false; - emitted_peerCertificateAvailable = false; - - out.clear(); - out_pending = 0; - packet_out.clear(); - packet_out_pending = 0; - - if(mode >= ResetSessionAndData) - { - peerCert = CertificateChain(); - peerValidity = ErrorValidityUnknown; - hostMismatch = false; - errorCode = (TLS::Error)-1; - - in.clear(); - to_net.clear(); - from_net.clear(); - unprocessed.clear(); - to_net_encoded = 0; - layer.reset(); - - packet_in.clear(); - packet_to_net.clear(); - packet_from_net.clear(); - packet_to_net_encoded.clear(); - } - - if(mode >= ResetAll) - { - localCert = CertificateChain(); - localKey = PrivateKey(); - trusted = CertificateCollection(); - con_ssfMode = true; - con_minSSF = 128; - con_maxSSF = -1; - con_cipherSuites = QStringList(); - tryCompress = false; - packet_mtu = -1; - issuerList.clear(); - session = TLSSession(); - } - } - - void start(bool serverMode) - { - state = Initializing; - server = serverMode; - - c->setup(serverMode, host, tryCompress); - - if(con_ssfMode) - c->setConstraints(con_minSSF, con_maxSSF); - else - c->setConstraints(con_cipherSuites); - - c->setCertificate(localCert, localKey); - c->setTrustedCertificates(trusted); - if(serverMode) - c->setIssuerList(issuerList); - if(!session.isNull()) - { - TLSSessionContext *sc = static_cast(session.context()); - c->setSessionId(*sc); - } - c->setMTU(packet_mtu); - - QCA_logTextMessage(QString("tls[%1]: c->start()").arg(q->objectName()), Logger::Information); - op = OpStart; - c->start(); - } - - void close() - { - QCA_logTextMessage(QString("tls[%1]: close").arg(q->objectName()), Logger::Information); - - if(state != Connected) - return; - - state = Closing; - c->shutdown(); - } - - void continueAfterStep() - { - QCA_logTextMessage(QString("tls[%1]: continueAfterStep").arg(q->objectName()), Logger::Information); - - if(!blocked) - return; - - blocked = false; - update(); - } - - void processNextAction() - { - if(actionQueue.isEmpty()) - { - if(need_update) - { - QCA_logTextMessage(QString("tls[%1]: need_update").arg(q->objectName()), Logger::Information); - update(); - } - return; - } - - Action a = actionQueue.takeFirst(); - - // set up for the next one, if necessary - if(!actionQueue.isEmpty() || need_update) - { - if(!actionTrigger.isActive()) - actionTrigger.start(); - } - - if(a.type == Action::ReadyRead) - { - emit q->readyRead(); - } - else if(a.type == Action::ReadyReadOutgoing) - { - emit q->readyReadOutgoing(); - } - else if(a.type == Action::Handshaken) - { - state = Connected; - - // write any app data waiting during handshake - if(!out.isEmpty()) - { - need_update = true; - if(!actionTrigger.isActive()) - actionTrigger.start(); - } - - QCA_logTextMessage(QString("tls[%1]: handshaken").arg(q->objectName()), Logger::Information); - - if(connect_handshaken) - { - blocked = true; - emit q->handshaken(); - } - } - else if(a.type == Action::Close) - { - unprocessed = c->unprocessed(); - reset(ResetSession); - emit q->closed(); - } - else if(a.type == Action::CheckPeerCertificate) - { - peerCert = c->peerCertificateChain(); - if(!peerCert.isEmpty()) - { - peerValidity = c->peerCertificateValidity(); - if(peerValidity == ValidityGood && !host.isEmpty() && !peerCert.primary().matchesHostName(host)) - hostMismatch = true; - } - - if(connect_peerCertificateAvailable) - { - blocked = true; - emitted_peerCertificateAvailable = true; - emit q->peerCertificateAvailable(); - } - } - else if(a.type == Action::CertificateRequested) - { - issuerList = c->issuerList(); - if(connect_certificateRequested) - { - blocked = true; - emitted_certificateRequested = true; - emit q->certificateRequested(); - } - } - else if(a.type == Action::HostNameReceived) - { - if(connect_hostNameReceived) - { - blocked = true; - emitted_hostNameReceived = true; - emit q->hostNameReceived(); - } - } - } - - void update() - { - QCA_logTextMessage(QString("tls[%1]: update").arg(q->objectName()), Logger::Information); - - if(blocked) - { - QCA_logTextMessage(QString("tls[%1]: ignoring update while blocked").arg(q->objectName()), Logger::Information); - return; - } - - if(!actionQueue.isEmpty()) - { - QCA_logTextMessage(QString("tls[%1]: ignoring update while processing actions").arg(q->objectName()), Logger::Information); - need_update = true; - return; - } - - // only allow one operation at a time - if(op != -1) - { - QCA_logTextMessage(QString("tls[%1]: ignoring update while operation active").arg(q->objectName()), Logger::Information); - need_update = true; - return; - } - - need_update = false; - - QByteArray arg_from_net, arg_from_app; - - if(state == Handshaking) - { - // during handshake, only send from_net (no app data) - - if(mode == TLS::Stream) - { - arg_from_net = from_net; - from_net.clear(); - } - else - { - // note: there may not be a packet - if(!packet_from_net.isEmpty()) - arg_from_net = packet_from_net.takeFirst(); - } - } - else - { - if(mode == TLS::Stream) - { - if(!from_net.isEmpty()) - { - arg_from_net = from_net; - from_net.clear(); - } - - if(!out.isEmpty()) - { - out_pending += out.size(); - arg_from_app = out; - out.clear(); - } - } - else - { - if(!packet_from_net.isEmpty()) - arg_from_net = packet_from_net.takeFirst(); - - if(!packet_out.isEmpty()) - { - arg_from_app = packet_out.takeFirst(); - ++packet_out_pending; - } - } - } - - if(arg_from_net.isEmpty() && arg_from_app.isEmpty() && !maybe_input) - { - QCA_logTextMessage(QString("tls[%1]: ignoring update: no output and no expected input").arg(q->objectName()), Logger::Information); - return; - } - - // clear this flag - maybe_input = false; - - QCA_logTextMessage(QString("tls[%1]: c->update").arg(q->objectName()), Logger::Information); - op = OpUpdate; - c->update(arg_from_net, arg_from_app); - } - - void start_finished() - { - bool ok = c->result() == TLSContext::Success; - if(!ok) - { - reset(ResetSession); - errorCode = TLS::ErrorInit; - emit q->error(); - return; - } - - state = Handshaking; - - // immediately update so we can get the first packet to send - maybe_input = true; - update(); - } - - void update_finished() - { - TLSContext::Result r = c->result(); - if(r == TLSContext::Error) - { - if(state == Handshaking || state == Closing) - { - reset(ResetSession); - errorCode = ErrorHandshake; - } - else - { - reset(ResetSession); - errorCode = ErrorCrypt; - } - - emit q->error(); - return; - } - - QByteArray c_to_net = c->to_net(); - if(!c_to_net.isEmpty()) - { - QCA_logTextMessage(QString("tls[%1]: to_net %2").arg(q->objectName(), QString::number(c_to_net.size())), Logger::Information); - } - - if(state == Closing) - { - if(mode == TLS::Stream) - to_net += c_to_net; - else - packet_to_net += c_to_net; - - if(!c_to_net.isEmpty()) - actionQueue += Action(Action::ReadyReadOutgoing); - - if(r == TLSContext::Success) - actionQueue += Action(Action::Close); - - processNextAction(); - return; - } - else if(state == Handshaking) - { - if(mode == TLS::Stream) - to_net += c_to_net; - else - packet_to_net += c_to_net; - - if(!c_to_net.isEmpty()) - actionQueue += Action(Action::ReadyReadOutgoing); - - bool clientHello = false; - bool serverHello = false; - if(server) - clientHello = c->clientHelloReceived(); - else - serverHello = c->serverHelloReceived(); - - // client specifies a host? - if(!emitted_hostNameReceived && clientHello) - { - host = c->hostName(); - if(!host.isEmpty()) - actionQueue += Action(Action::HostNameReceived); - } - - // successful handshake or server hello means there might be a peer cert - if(!emitted_peerCertificateAvailable && (r == TLSContext::Success || (!server && serverHello))) - actionQueue += Action(Action::CheckPeerCertificate); - - // server requests a cert from us? - if(!emitted_certificateRequested && (serverHello && c->certificateRequested())) - actionQueue += Action(Action::CertificateRequested); - - if(r == TLSContext::Success) - { - sessionInfo = c->sessionInfo(); - if(sessionInfo.id) - { - TLSSessionContext *sc = static_cast(sessionInfo.id->clone()); - session.change(sc); - } - - actionQueue += Action(Action::Handshaken); - } - - processNextAction(); - return; - } - else // Connected - { - QByteArray c_to_app = c->to_app(); - if(!c_to_app.isEmpty()) - { - QCA_logTextMessage(QString("tls[%1]: to_app %2").arg(q->objectName(), QString::number(c_to_app.size())), Logger::Information); - } - - bool eof = c->eof(); - int enc = -1; - if(!c_to_net.isEmpty()) - enc = c->encoded(); - - bool io_pending = false; - if(mode == TLS::Stream) - { - if(!c_to_net.isEmpty()) - out_pending -= enc; - - if(out_pending > 0) - { - maybe_input = true; - io_pending = true; - } - - if(!out.isEmpty()) - io_pending = true; - } - else - { - if(!c_to_net.isEmpty()) - --packet_out_pending; - - if(packet_out_pending > 0) - { - maybe_input = true; - io_pending = true; - } - - if(!packet_out.isEmpty()) - io_pending = true; - } - - if(mode == TLS::Stream) - { - to_net += c_to_net; - in += c_to_app; - to_net_encoded += enc; - } - else - { - packet_to_net += c_to_net; - packet_in += c_to_app; - } - - if(!c_to_net.isEmpty()) - actionQueue += Action(Action::ReadyReadOutgoing); - - if(!c_to_app.isEmpty()) - actionQueue += Action(Action::ReadyRead); - - if(eof) - { - close(); - maybe_input = true; - } - - if(eof || io_pending) - { - QCA_logTextMessage(QString("tls[%1]: eof || io_pending").arg(q->objectName()), Logger::Information); - update(); - } - - processNextAction(); - return; - } - } + enum { + OpStart, + OpUpdate + }; + + enum State { + Inactive, + Initializing, + Handshaking, + Connected, + Closing + }; + + class Action + { + public: + enum Type { + ReadyRead, + ReadyReadOutgoing, + Handshaken, + Close, + CheckPeerCertificate, + CertificateRequested, + HostNameReceived + }; + + int type; + + Action(int _type) : type(_type) + { + } + }; + + TLS *q; + TLSContext *c; + TLS::Mode mode; + + // signal connected flags + bool connect_hostNameReceived; + bool connect_certificateRequested; + bool connect_peerCertificateAvailable; + bool connect_handshaken; + + // persistent settings (survives ResetSessionAndData) + CertificateChain localCert; + PrivateKey localKey; + CertificateCollection trusted; + bool con_ssfMode; + int con_minSSF, con_maxSSF; + QStringList con_cipherSuites; + bool tryCompress; + int packet_mtu; + QList issuerList; + TLSSession session; + + // session + State state; + bool blocked; + bool server; + QString host; + TLSContext::SessionInfo sessionInfo; + SafeTimer actionTrigger; + int op; + QList actionQueue; + bool need_update; + bool maybe_input; + bool emitted_hostNameReceived; + bool emitted_certificateRequested; + bool emitted_peerCertificateAvailable; + + // data (survives ResetSession) + CertificateChain peerCert; + Validity peerValidity; + bool hostMismatch; + Error errorCode; + + // stream i/o + QByteArray in, out; + QByteArray to_net, from_net; + QByteArray unprocessed; + int out_pending; + int to_net_encoded; + LayerTracker layer; + + // datagram i/o + QList packet_in, packet_out; + QList packet_to_net, packet_from_net; + int packet_out_pending; // packet count + QList packet_to_net_encoded; + + Private(TLS *_q, TLS::Mode _mode) : QObject(_q), q(_q), mode(_mode), actionTrigger(this) + { + // c is 0 during initial reset, so we don't redundantly reset it + c = 0; + connect_hostNameReceived = false; + connect_certificateRequested = false; + connect_peerCertificateAvailable = false; + connect_handshaken = false; + server = false; + + connect(&actionTrigger, SIGNAL(timeout()), SLOT(doNextAction())); + actionTrigger.setSingleShot(true); + + reset(ResetAll); + + c = static_cast(q->context()); + + // parent the context to us, so that moveToThread works + c->setParent(this); + + connect(c, SIGNAL(resultsReady()), SLOT(tls_resultsReady())); + connect(c, SIGNAL(dtlsTimeout()), SLOT(tls_dtlsTimeout())); + } + + ~Private() + { + // context is owned by Algorithm, unparent so we don't double-delete + c->setParent(0); + } + + void reset(ResetMode mode) + { + if (c) { + c->reset(); + } + + // if we reset while in client mode, then clear this list + // (it should only persist when used for server mode) + if (!server) { + issuerList.clear(); + } + + state = Inactive; + blocked = false; + server = false; + host = QString(); + sessionInfo = TLSContext::SessionInfo(); + actionTrigger.stop(); + op = -1; + actionQueue.clear(); + need_update = false; + maybe_input = false; + emitted_hostNameReceived = false; + emitted_certificateRequested = false; + emitted_peerCertificateAvailable = false; + + out.clear(); + out_pending = 0; + packet_out.clear(); + packet_out_pending = 0; + + if (mode >= ResetSessionAndData) { + peerCert = CertificateChain(); + peerValidity = ErrorValidityUnknown; + hostMismatch = false; + errorCode = (TLS::Error) - 1; + + in.clear(); + to_net.clear(); + from_net.clear(); + unprocessed.clear(); + to_net_encoded = 0; + layer.reset(); + + packet_in.clear(); + packet_to_net.clear(); + packet_from_net.clear(); + packet_to_net_encoded.clear(); + } + + if (mode >= ResetAll) { + localCert = CertificateChain(); + localKey = PrivateKey(); + trusted = CertificateCollection(); + con_ssfMode = true; + con_minSSF = 128; + con_maxSSF = -1; + con_cipherSuites = QStringList(); + tryCompress = false; + packet_mtu = -1; + issuerList.clear(); + session = TLSSession(); + } + } + + void start(bool serverMode) + { + state = Initializing; + server = serverMode; + + c->setup(serverMode, host, tryCompress); + + if (con_ssfMode) { + c->setConstraints(con_minSSF, con_maxSSF); + } else { + c->setConstraints(con_cipherSuites); + } + + c->setCertificate(localCert, localKey); + c->setTrustedCertificates(trusted); + if (serverMode) { + c->setIssuerList(issuerList); + } + if (!session.isNull()) { + TLSSessionContext *sc = static_cast(session.context()); + c->setSessionId(*sc); + } + c->setMTU(packet_mtu); + + QCA_logTextMessage(QString("tls[%1]: c->start()").arg(q->objectName()), Logger::Information); + op = OpStart; + c->start(); + } + + void close() + { + QCA_logTextMessage(QString("tls[%1]: close").arg(q->objectName()), Logger::Information); + + if (state != Connected) { + return; + } + + state = Closing; + c->shutdown(); + } + + void continueAfterStep() + { + QCA_logTextMessage(QString("tls[%1]: continueAfterStep").arg(q->objectName()), Logger::Information); + + if (!blocked) { + return; + } + + blocked = false; + update(); + } + + void processNextAction() + { + if (actionQueue.isEmpty()) { + if (need_update) { + QCA_logTextMessage(QString("tls[%1]: need_update").arg(q->objectName()), Logger::Information); + update(); + } + return; + } + + Action a = actionQueue.takeFirst(); + + // set up for the next one, if necessary + if (!actionQueue.isEmpty() || need_update) { + if (!actionTrigger.isActive()) { + actionTrigger.start(); + } + } + + if (a.type == Action::ReadyRead) { + emit q->readyRead(); + } else if (a.type == Action::ReadyReadOutgoing) { + emit q->readyReadOutgoing(); + } else if (a.type == Action::Handshaken) { + state = Connected; + + // write any app data waiting during handshake + if (!out.isEmpty()) { + need_update = true; + if (!actionTrigger.isActive()) { + actionTrigger.start(); + } + } + + QCA_logTextMessage(QString("tls[%1]: handshaken").arg(q->objectName()), Logger::Information); + + if (connect_handshaken) { + blocked = true; + emit q->handshaken(); + } + } else if (a.type == Action::Close) { + unprocessed = c->unprocessed(); + reset(ResetSession); + emit q->closed(); + } else if (a.type == Action::CheckPeerCertificate) { + peerCert = c->peerCertificateChain(); + if (!peerCert.isEmpty()) { + peerValidity = c->peerCertificateValidity(); + if (peerValidity == ValidityGood && !host.isEmpty() && !peerCert.primary().matchesHostName(host)) { + hostMismatch = true; + } + } + + if (connect_peerCertificateAvailable) { + blocked = true; + emitted_peerCertificateAvailable = true; + emit q->peerCertificateAvailable(); + } + } else if (a.type == Action::CertificateRequested) { + issuerList = c->issuerList(); + if (connect_certificateRequested) { + blocked = true; + emitted_certificateRequested = true; + emit q->certificateRequested(); + } + } else if (a.type == Action::HostNameReceived) { + if (connect_hostNameReceived) { + blocked = true; + emitted_hostNameReceived = true; + emit q->hostNameReceived(); + } + } + } + + void update() + { + QCA_logTextMessage(QString("tls[%1]: update").arg(q->objectName()), Logger::Information); + + if (blocked) { + QCA_logTextMessage(QString("tls[%1]: ignoring update while blocked").arg(q->objectName()), Logger::Information); + return; + } + + if (!actionQueue.isEmpty()) { + QCA_logTextMessage(QString("tls[%1]: ignoring update while processing actions").arg(q->objectName()), Logger::Information); + need_update = true; + return; + } + + // only allow one operation at a time + if (op != -1) { + QCA_logTextMessage(QString("tls[%1]: ignoring update while operation active").arg(q->objectName()), Logger::Information); + need_update = true; + return; + } + + need_update = false; + + QByteArray arg_from_net, arg_from_app; + + if (state == Handshaking) { + // during handshake, only send from_net (no app data) + + if (mode == TLS::Stream) { + arg_from_net = from_net; + from_net.clear(); + } else { + // note: there may not be a packet + if (!packet_from_net.isEmpty()) { + arg_from_net = packet_from_net.takeFirst(); + } + } + } else { + if (mode == TLS::Stream) { + if (!from_net.isEmpty()) { + arg_from_net = from_net; + from_net.clear(); + } + + if (!out.isEmpty()) { + out_pending += out.size(); + arg_from_app = out; + out.clear(); + } + } else { + if (!packet_from_net.isEmpty()) { + arg_from_net = packet_from_net.takeFirst(); + } + + if (!packet_out.isEmpty()) { + arg_from_app = packet_out.takeFirst(); + ++packet_out_pending; + } + } + } + + if (arg_from_net.isEmpty() && arg_from_app.isEmpty() && !maybe_input) { + QCA_logTextMessage(QString("tls[%1]: ignoring update: no output and no expected input").arg(q->objectName()), Logger::Information); + return; + } + + // clear this flag + maybe_input = false; + + QCA_logTextMessage(QString("tls[%1]: c->update").arg(q->objectName()), Logger::Information); + op = OpUpdate; + c->update(arg_from_net, arg_from_app); + } + + void start_finished() + { + bool ok = c->result() == TLSContext::Success; + if (!ok) { + reset(ResetSession); + errorCode = TLS::ErrorInit; + emit q->error(); + return; + } + + state = Handshaking; + + // immediately update so we can get the first packet to send + maybe_input = true; + update(); + } + + void update_finished() + { + TLSContext::Result r = c->result(); + if (r == TLSContext::Error) { + if (state == Handshaking || state == Closing) { + reset(ResetSession); + errorCode = ErrorHandshake; + } else { + reset(ResetSession); + errorCode = ErrorCrypt; + } + + emit q->error(); + return; + } + + QByteArray c_to_net = c->to_net(); + if (!c_to_net.isEmpty()) { + QCA_logTextMessage(QString("tls[%1]: to_net %2").arg(q->objectName(), QString::number(c_to_net.size())), Logger::Information); + } + + if (state == Closing) { + if (mode == TLS::Stream) { + to_net += c_to_net; + } else { + packet_to_net += c_to_net; + } + + if (!c_to_net.isEmpty()) { + actionQueue += Action(Action::ReadyReadOutgoing); + } + + if (r == TLSContext::Success) { + actionQueue += Action(Action::Close); + } + + processNextAction(); + return; + } else if (state == Handshaking) { + if (mode == TLS::Stream) { + to_net += c_to_net; + } else { + packet_to_net += c_to_net; + } + + if (!c_to_net.isEmpty()) { + actionQueue += Action(Action::ReadyReadOutgoing); + } + + bool clientHello = false; + bool serverHello = false; + if (server) { + clientHello = c->clientHelloReceived(); + } else { + serverHello = c->serverHelloReceived(); + } + + // client specifies a host? + if (!emitted_hostNameReceived && clientHello) { + host = c->hostName(); + if (!host.isEmpty()) { + actionQueue += Action(Action::HostNameReceived); + } + } + + // successful handshake or server hello means there might be a peer cert + if (!emitted_peerCertificateAvailable && (r == TLSContext::Success || (!server && serverHello))) { + actionQueue += Action(Action::CheckPeerCertificate); + } + + // server requests a cert from us? + if (!emitted_certificateRequested && (serverHello && c->certificateRequested())) { + actionQueue += Action(Action::CertificateRequested); + } + + if (r == TLSContext::Success) { + sessionInfo = c->sessionInfo(); + if (sessionInfo.id) { + TLSSessionContext *sc = static_cast(sessionInfo.id->clone()); + session.change(sc); + } + + actionQueue += Action(Action::Handshaken); + } + + processNextAction(); + return; + } else { // Connected + QByteArray c_to_app = c->to_app(); + if (!c_to_app.isEmpty()) { + QCA_logTextMessage(QString("tls[%1]: to_app %2").arg(q->objectName(), QString::number(c_to_app.size())), Logger::Information); + } + + bool eof = c->eof(); + int enc = -1; + if (!c_to_net.isEmpty()) { + enc = c->encoded(); + } + + bool io_pending = false; + if (mode == TLS::Stream) { + if (!c_to_net.isEmpty()) { + out_pending -= enc; + } + + if (out_pending > 0) { + maybe_input = true; + io_pending = true; + } + + if (!out.isEmpty()) { + io_pending = true; + } + } else { + if (!c_to_net.isEmpty()) { + --packet_out_pending; + } + + if (packet_out_pending > 0) { + maybe_input = true; + io_pending = true; + } + + if (!packet_out.isEmpty()) { + io_pending = true; + } + } + + if (mode == TLS::Stream) { + to_net += c_to_net; + in += c_to_app; + to_net_encoded += enc; + } else { + packet_to_net += c_to_net; + packet_in += c_to_app; + } + + if (!c_to_net.isEmpty()) { + actionQueue += Action(Action::ReadyReadOutgoing); + } + + if (!c_to_app.isEmpty()) { + actionQueue += Action(Action::ReadyRead); + } + + if (eof) { + close(); + maybe_input = true; + } + + if (eof || io_pending) { + QCA_logTextMessage(QString("tls[%1]: eof || io_pending").arg(q->objectName()), Logger::Information); + update(); + } + + processNextAction(); + return; + } + } private slots: - void tls_resultsReady() - { - QCA_logTextMessage(QString("tls[%1]: c->resultsReady()").arg(q->objectName()), Logger::Information); - - Q_ASSERT(op != -1); - - int last_op = op; - op = -1; - - if(last_op == OpStart) - start_finished(); - else // OpUpdate - update_finished(); - } - - void tls_dtlsTimeout() - { - QCA_logTextMessage(QString("tls[%1]: c->dtlsTimeout()").arg(q->objectName()), Logger::Information); - - maybe_input = true; - update(); - } - - void doNextAction() - { - processNextAction(); - } + void tls_resultsReady() + { + QCA_logTextMessage(QString("tls[%1]: c->resultsReady()").arg(q->objectName()), Logger::Information); + + Q_ASSERT(op != -1); + + int last_op = op; + op = -1; + + if (last_op == OpStart) { + start_finished(); + } else { // OpUpdate + update_finished(); + } + } + + void tls_dtlsTimeout() + { + QCA_logTextMessage(QString("tls[%1]: c->dtlsTimeout()").arg(q->objectName()), Logger::Information); + + maybe_input = true; + update(); + } + + void doNextAction() + { + processNextAction(); + } }; TLS::TLS(QObject *parent, const QString &provider) -:SecureLayer(parent), Algorithm("tls", provider) + : SecureLayer(parent), Algorithm("tls", provider) { - d = new Private(this, TLS::Stream); + d = new Private(this, TLS::Stream); } TLS::TLS(Mode mode, QObject *parent, const QString &provider) -:SecureLayer(parent), Algorithm(mode == Stream ? "tls" : "dtls", provider) + : SecureLayer(parent), Algorithm(mode == Stream ? "tls" : "dtls", provider) { - d = new Private(this, mode); + d = new Private(this, mode); } TLS::~TLS() { - delete d; + delete d; } void TLS::reset() { - d->reset(ResetAll); + d->reset(ResetAll); } QStringList TLS::supportedCipherSuites(const Version &version) const { - return d->c->supportedCipherSuites(version); + return d->c->supportedCipherSuites(version); } void TLS::setCertificate(const CertificateChain &cert, const PrivateKey &key) { - d->localCert = cert; - d->localKey = key; - if(d->state != TLS::Private::Inactive) - d->c->setCertificate(cert, key); + d->localCert = cert; + d->localKey = key; + if (d->state != TLS::Private::Inactive) { + d->c->setCertificate(cert, key); + } } void TLS::setCertificate(const KeyBundle &kb) { - setCertificate(kb.certificateChain(), kb.privateKey()); + setCertificate(kb.certificateChain(), kb.privateKey()); } CertificateCollection TLS::trustedCertificates() const { - return d->trusted; + return d->trusted; } void TLS::setTrustedCertificates(const CertificateCollection &trusted) { - d->trusted = trusted; - if(d->state != TLS::Private::Inactive) - d->c->setTrustedCertificates(trusted); + d->trusted = trusted; + if (d->state != TLS::Private::Inactive) { + d->c->setTrustedCertificates(trusted); + } } void TLS::setConstraints(SecurityLevel s) { - int min = 128; - switch(s) - { - case SL_None: - min = 0; - break; - case SL_Integrity: - min = 1; - break; - case SL_Export: - min = 40; - break; - case SL_Baseline: - min = 128; - break; - case SL_High: - min = 129; - break; - case SL_Highest: - min = qMax(129, d->c->maxSSF()); - break; - } - - d->con_ssfMode = true; - d->con_minSSF = min; - d->con_maxSSF = -1; - - if(d->state != TLS::Private::Inactive) - d->c->setConstraints(d->con_minSSF, d->con_maxSSF); + int min = 128; + switch (s) { + case SL_None: + min = 0; + break; + case SL_Integrity: + min = 1; + break; + case SL_Export: + min = 40; + break; + case SL_Baseline: + min = 128; + break; + case SL_High: + min = 129; + break; + case SL_Highest: + min = qMax(129, d->c->maxSSF()); + break; + } + + d->con_ssfMode = true; + d->con_minSSF = min; + d->con_maxSSF = -1; + + if (d->state != TLS::Private::Inactive) { + d->c->setConstraints(d->con_minSSF, d->con_maxSSF); + } } void TLS::setConstraints(int minSSF, int maxSSF) { - d->con_ssfMode = true; - d->con_minSSF = minSSF; - d->con_maxSSF = maxSSF; + d->con_ssfMode = true; + d->con_minSSF = minSSF; + d->con_maxSSF = maxSSF; - if(d->state != TLS::Private::Inactive) - d->c->setConstraints(d->con_minSSF, d->con_maxSSF); + if (d->state != TLS::Private::Inactive) { + d->c->setConstraints(d->con_minSSF, d->con_maxSSF); + } } void TLS::setConstraints(const QStringList &cipherSuiteList) { - d->con_ssfMode = false; - d->con_cipherSuites = cipherSuiteList; + d->con_ssfMode = false; + d->con_cipherSuites = cipherSuiteList; - if(d->state != TLS::Private::Inactive) - d->c->setConstraints(d->con_cipherSuites); + if (d->state != TLS::Private::Inactive) { + d->c->setConstraints(d->con_cipherSuites); + } } QList TLS::issuerList() const { - return d->issuerList; + return d->issuerList; } void TLS::setIssuerList(const QList &issuers) { - d->issuerList = issuers; - if(d->state != TLS::Private::Inactive) - d->c->setIssuerList(issuers); + d->issuerList = issuers; + if (d->state != TLS::Private::Inactive) { + d->c->setIssuerList(issuers); + } } void TLS::setSession(const TLSSession &session) { - d->session = session; + d->session = session; } bool TLS::canCompress() const { - return d->c->canCompress(); + return d->c->canCompress(); } bool TLS::canSetHostName() const { - return d->c->canSetHostName(); + return d->c->canSetHostName(); } bool TLS::compressionEnabled() const { - return d->tryCompress; + return d->tryCompress; } void TLS::setCompressionEnabled(bool b) { - d->tryCompress = b; + d->tryCompress = b; } void TLS::startClient(const QString &host) { - d->reset(ResetSessionAndData); - d->host = host; - d->issuerList.clear(); + d->reset(ResetSessionAndData); + d->host = host; + d->issuerList.clear(); - // client mode - d->start(false); + // client mode + d->start(false); } void TLS::startServer() { - d->reset(ResetSessionAndData); + d->reset(ResetSessionAndData); - // server mode - d->start(true); + // server mode + d->start(true); } void TLS::continueAfterStep() { - d->continueAfterStep(); + d->continueAfterStep(); } bool TLS::isHandshaken() const { - if(d->state == TLS::Private::Connected || d->state == TLS::Private::Closing) - return true; - else - return false; + if (d->state == TLS::Private::Connected || d->state == TLS::Private::Closing) { + return true; + } else { + return false; + } } bool TLS::isCompressed() const { - return d->sessionInfo.isCompressed; + return d->sessionInfo.isCompressed; } TLS::Version TLS::version() const { - return d->sessionInfo.version; + return d->sessionInfo.version; } QString TLS::cipherSuite() const { - return d->sessionInfo.cipherSuite; + return d->sessionInfo.cipherSuite; } int TLS::cipherBits() const { - return d->sessionInfo.cipherBits; + return d->sessionInfo.cipherBits; } int TLS::cipherMaxBits() const { - return d->sessionInfo.cipherMaxBits; + return d->sessionInfo.cipherMaxBits; } TLSSession TLS::session() const { - return d->session; + return d->session; } TLS::Error TLS::errorCode() const { - return d->errorCode; + return d->errorCode; } TLS::IdentityResult TLS::peerIdentityResult() const { - if(d->peerCert.isEmpty()) - return NoCertificate; + if (d->peerCert.isEmpty()) { + return NoCertificate; + } - if(d->peerValidity != ValidityGood) - return InvalidCertificate; + if (d->peerValidity != ValidityGood) { + return InvalidCertificate; + } - if(d->hostMismatch) - return HostMismatch; + if (d->hostMismatch) { + return HostMismatch; + } - return Valid; + return Valid; } Validity TLS::peerCertificateValidity() const { - return d->peerValidity; + return d->peerValidity; } CertificateChain TLS::localCertificateChain() const { - return d->localCert; + return d->localCert; } PrivateKey TLS::localPrivateKey() const { - return d->localKey; + return d->localKey; } CertificateChain TLS::peerCertificateChain() const { - return d->peerCert; + return d->peerCert; } bool TLS::isClosable() const { - return true; + return true; } int TLS::bytesAvailable() const { - if(d->mode == Stream) - return d->in.size(); - else - return 0; + if (d->mode == Stream) { + return d->in.size(); + } else { + return 0; + } } int TLS::bytesOutgoingAvailable() const { - if(d->mode == Stream) - return d->to_net.size(); - else - return 0; + if (d->mode == Stream) { + return d->to_net.size(); + } else { + return 0; + } } void TLS::close() { - d->close(); - d->update(); + d->close(); + d->update(); } void TLS::write(const QByteArray &a) { - if(d->mode == Stream) - { - d->out.append(a); - d->layer.addPlain(a.size()); - } - else - d->packet_out.append(a); - QCA_logTextMessage(QString("tls[%1]: write").arg(objectName()), Logger::Information); - d->update(); + if (d->mode == Stream) { + d->out.append(a); + d->layer.addPlain(a.size()); + } else { + d->packet_out.append(a); + } + QCA_logTextMessage(QString("tls[%1]: write").arg(objectName()), Logger::Information); + d->update(); } QByteArray TLS::read() { - if(d->mode == Stream) - { - QByteArray a = d->in; - d->in.clear(); - return a; - } - else - { - if(!d->packet_in.isEmpty()) - return d->packet_in.takeFirst(); - else - return QByteArray(); - } + if (d->mode == Stream) { + QByteArray a = d->in; + d->in.clear(); + return a; + } else { + if (!d->packet_in.isEmpty()) { + return d->packet_in.takeFirst(); + } else { + return QByteArray(); + } + } } void TLS::writeIncoming(const QByteArray &a) { - if(d->mode == Stream) - d->from_net.append(a); - else - d->packet_from_net.append(a); - QCA_logTextMessage(QString("tls[%1]: writeIncoming %2").arg(objectName(), QString::number(a.size())), Logger::Information); - d->update(); + if (d->mode == Stream) { + d->from_net.append(a); + } else { + d->packet_from_net.append(a); + } + QCA_logTextMessage(QString("tls[%1]: writeIncoming %2").arg(objectName(), QString::number(a.size())), Logger::Information); + d->update(); } QByteArray TLS::readOutgoing(int *plainBytes) { - if(d->mode == Stream) - { - QByteArray a = d->to_net; - d->to_net.clear(); - if(plainBytes) - *plainBytes = d->to_net_encoded; - d->layer.specifyEncoded(a.size(), d->to_net_encoded); - d->to_net_encoded = 0; - return a; - } - else - { - if(!d->packet_to_net.isEmpty()) - { - QByteArray a = d->packet_to_net.takeFirst(); - int x = d->packet_to_net_encoded.takeFirst(); - if(plainBytes) - *plainBytes = x; - return a; - } - else - { - if(plainBytes) - *plainBytes = 0; - return QByteArray(); - } - } + if (d->mode == Stream) { + QByteArray a = d->to_net; + d->to_net.clear(); + if (plainBytes) { + *plainBytes = d->to_net_encoded; + } + d->layer.specifyEncoded(a.size(), d->to_net_encoded); + d->to_net_encoded = 0; + return a; + } else { + if (!d->packet_to_net.isEmpty()) { + QByteArray a = d->packet_to_net.takeFirst(); + int x = d->packet_to_net_encoded.takeFirst(); + if (plainBytes) { + *plainBytes = x; + } + return a; + } else { + if (plainBytes) { + *plainBytes = 0; + } + return QByteArray(); + } + } } QByteArray TLS::readUnprocessed() { - if(d->mode == Stream) - { - QByteArray a = d->unprocessed; - d->unprocessed.clear(); - return a; - } - else - return QByteArray(); + if (d->mode == Stream) { + QByteArray a = d->unprocessed; + d->unprocessed.clear(); + return a; + } else { + return QByteArray(); + } } int TLS::convertBytesWritten(qint64 bytes) { - return d->layer.finished(bytes); + return d->layer.finished(bytes); } int TLS::packetsAvailable() const { - return d->packet_in.count(); + return d->packet_in.count(); } int TLS::packetsOutgoingAvailable() const { - return d->packet_to_net.count(); + return d->packet_to_net.count(); } int TLS::packetMTU() const { - return d->packet_mtu; + return d->packet_mtu; } void TLS::setPacketMTU(int size) const { - d->packet_mtu = size; - if(d->state != TLS::Private::Inactive) - d->c->setMTU(size); + d->packet_mtu = size; + if (d->state != TLS::Private::Inactive) { + d->c->setMTU(size); + } } #if QT_VERSION >= 0x050000 void TLS::connectNotify(const QMetaMethod &signal) { - if(signal == QMetaMethod::fromSignal(&TLS::hostNameReceived)) - d->connect_hostNameReceived = true; - else if(signal == QMetaMethod::fromSignal(&TLS::certificateRequested)) - d->connect_certificateRequested = true; - else if(signal == QMetaMethod::fromSignal(&TLS::peerCertificateAvailable)) - d->connect_peerCertificateAvailable = true; - else if(signal == QMetaMethod::fromSignal(&TLS::handshaken)) - d->connect_handshaken = true; + if (signal == QMetaMethod::fromSignal(&TLS::hostNameReceived)) { + d->connect_hostNameReceived = true; + } else if (signal == QMetaMethod::fromSignal(&TLS::certificateRequested)) { + d->connect_certificateRequested = true; + } else if (signal == QMetaMethod::fromSignal(&TLS::peerCertificateAvailable)) { + d->connect_peerCertificateAvailable = true; + } else if (signal == QMetaMethod::fromSignal(&TLS::handshaken)) { + d->connect_handshaken = true; + } } void TLS::disconnectNotify(const QMetaMethod &signal) { - if(signal == QMetaMethod::fromSignal(&TLS::hostNameReceived)) - d->connect_hostNameReceived = false; - else if(signal == QMetaMethod::fromSignal(&TLS::certificateRequested)) - d->connect_certificateRequested = false; - else if(signal == QMetaMethod::fromSignal(&TLS::peerCertificateAvailable)) - d->connect_peerCertificateAvailable = false; - else if(signal == QMetaMethod::fromSignal(&TLS::handshaken)) - d->connect_handshaken = false; + if (signal == QMetaMethod::fromSignal(&TLS::hostNameReceived)) { + d->connect_hostNameReceived = false; + } else if (signal == QMetaMethod::fromSignal(&TLS::certificateRequested)) { + d->connect_certificateRequested = false; + } else if (signal == QMetaMethod::fromSignal(&TLS::peerCertificateAvailable)) { + d->connect_peerCertificateAvailable = false; + } else if (signal == QMetaMethod::fromSignal(&TLS::handshaken)) { + d->connect_handshaken = false; + } } #else void TLS::connectNotify(const char *signal) { - if(signal == QMetaObject::normalizedSignature(SIGNAL(hostNameReceived()))) - d->connect_hostNameReceived = true; - else if(signal == QMetaObject::normalizedSignature(SIGNAL(certificateRequested()))) - d->connect_certificateRequested = true; - else if(signal == QMetaObject::normalizedSignature(SIGNAL(peerCertificateAvailable()))) - d->connect_peerCertificateAvailable = true; - else if(signal == QMetaObject::normalizedSignature(SIGNAL(handshaken()))) - d->connect_handshaken = true; + if (signal == QMetaObject::normalizedSignature(SIGNAL(hostNameReceived()))) { + d->connect_hostNameReceived = true; + } else if (signal == QMetaObject::normalizedSignature(SIGNAL(certificateRequested()))) { + d->connect_certificateRequested = true; + } else if (signal == QMetaObject::normalizedSignature(SIGNAL(peerCertificateAvailable()))) { + d->connect_peerCertificateAvailable = true; + } else if (signal == QMetaObject::normalizedSignature(SIGNAL(handshaken()))) { + d->connect_handshaken = true; + } } void TLS::disconnectNotify(const char *signal) { - if(signal == QMetaObject::normalizedSignature(SIGNAL(hostNameReceived()))) - d->connect_hostNameReceived = false; - else if(signal == QMetaObject::normalizedSignature(SIGNAL(certificateRequested()))) - d->connect_certificateRequested = false; - else if(signal == QMetaObject::normalizedSignature(SIGNAL(peerCertificateAvailable()))) - d->connect_peerCertificateAvailable = false; - else if(signal == QMetaObject::normalizedSignature(SIGNAL(handshaken()))) - d->connect_handshaken = false; + if (signal == QMetaObject::normalizedSignature(SIGNAL(hostNameReceived()))) { + d->connect_hostNameReceived = false; + } else if (signal == QMetaObject::normalizedSignature(SIGNAL(certificateRequested()))) { + d->connect_certificateRequested = false; + } else if (signal == QMetaObject::normalizedSignature(SIGNAL(peerCertificateAvailable()))) { + d->connect_peerCertificateAvailable = false; + } else if (signal == QMetaObject::normalizedSignature(SIGNAL(handshaken()))) { + d->connect_handshaken = false; + } } #endif @@ -1233,57 +1200,57 @@ class SASL::Params::Private { public: - bool needUsername, canSendAuthzid, needPassword, canSendRealm; + bool needUsername, canSendAuthzid, needPassword, canSendRealm; }; SASL::Params::Params() -:d(new Private) + : d(new Private) { } SASL::Params::Params(bool user, bool authzid, bool pass, bool realm) -:d(new Private) + : d(new Private) { - d->needUsername = user; - d->canSendAuthzid = authzid; - d->needPassword = pass; - d->canSendRealm = realm; + d->needUsername = user; + d->canSendAuthzid = authzid; + d->needPassword = pass; + d->canSendRealm = realm; } SASL::Params::Params(const SASL::Params &from) -:d(new Private(*from.d)) + : d(new Private(*from.d)) { } SASL::Params::~Params() { - delete d; + delete d; } -SASL::Params & SASL::Params::operator=(const SASL::Params &from) +SASL::Params &SASL::Params::operator=(const SASL::Params &from) { - *d = *from.d; - return *this; + *d = *from.d; + return *this; } bool SASL::Params::needUsername() const { - return d->needUsername; + return d->needUsername; } bool SASL::Params::canSendAuthzid() const { - return d->canSendAuthzid; + return d->canSendAuthzid; } bool SASL::Params::needPassword() const { - return d->needPassword; + return d->needPassword; } bool SASL::Params::canSendRealm() const { - return d->canSendRealm; + return d->canSendRealm; } //---------------------------------------------------------------------------- @@ -1305,713 +1272,678 @@ class SASL::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - enum - { - OpStart, - OpServerFirstStep, - OpNextStep, - OpTryAgain, - OpUpdate - }; - - class Action - { - public: - enum Type - { - ClientStarted, - NextStep, - Authenticated, - ReadyRead, - ReadyReadOutgoing - }; - - int type; - QByteArray stepData; - bool haveInit; - - Action(int _type) : type(_type) - { - } - - Action(int _type, const QByteArray &_stepData) : type(_type), stepData(_stepData) - { - } - - Action(int _type, bool _haveInit, const QByteArray &_stepData) : type(_type), stepData(_stepData), haveInit(_haveInit) - { - } - }; - - SASL *q; - SASLContext *c; - - // persistent settings (survives ResetSessionAndData) - AuthFlags auth_flags; - int ssfmin, ssfmax; - QString ext_authid; - int ext_ssf; - bool localSet, remoteSet; - SASLContext::HostPort local, remote; - bool set_username, set_authzid, set_password, set_realm; - QString username, authzid, realm; - SecureArray password; - - // session - bool server; - QStringList mechlist; - QString server_realm; - bool allowClientSendFirst; - bool disableServerSendLast; - SafeTimer actionTrigger; - int op; - QList actionQueue; - bool need_update; - bool first; - bool authed; - - // data (survives ResetSession) - QString mech; // selected mech - Error errorCode; - - // stream i/o - QByteArray in, out; - QByteArray to_net, from_net; - int out_pending; - int to_net_encoded; - LayerTracker layer; - - Private(SASL *_q) : QObject(_q), q(_q), actionTrigger(this) - { - c = 0; - set_username = false; - set_authzid = false; - set_password = false; - set_realm = false; - - connect(&actionTrigger, SIGNAL(timeout()), SLOT(doNextAction())); - actionTrigger.setSingleShot(true); - - reset(ResetAll); - - c = static_cast(q->context()); - - // parent the context to us, so that moveToThread works - c->setParent(this); - - connect(c, SIGNAL(resultsReady()), SLOT(sasl_resultsReady())); - } - - ~Private() - { - // context is owned by Algorithm, unparent so we don't double-delete - c->setParent(0); - } - - void reset(ResetMode mode) - { - if(c) - c->reset(); - - server = false; - mechlist.clear(); - server_realm = QString(); - allowClientSendFirst = false; - disableServerSendLast = true; - actionTrigger.stop(); - op = -1; - actionQueue.clear(); - need_update = false; - first = false; - authed = false; - - out.clear(); - out_pending = 0; - - if(mode >= ResetSessionAndData) - { - mech = QString(); - errorCode = (SASL::Error)-1; - - in.clear(); - to_net.clear(); - from_net.clear(); - to_net_encoded = 0; - layer.reset(); - } - - if(mode >= ResetAll) - { - auth_flags = SASL::AuthFlagsNone; - ssfmin = 0; - ssfmax = 0; - ext_authid = QString(); - ext_ssf = 0; - localSet = false; - remoteSet = false; - local = SASLContext::HostPort(); - remote = SASLContext::HostPort(); - - set_username = false; - username = QString(); - set_authzid = false; - authzid = QString(); - set_password = false; - password = SecureArray(); - set_realm = false; - realm = QString(); - } - } - - void setup(const QString &service, const QString &host) - { - c->setup(service, host, localSet ? &local : 0, remoteSet ? &remote : 0, ext_authid, ext_ssf); - c->setConstraints(auth_flags, ssfmin, ssfmax); - - QString *p_username = 0; - QString *p_authzid = 0; - SecureArray *p_password = 0; - QString *p_realm = 0; - - if(set_username) - p_username = &username; - if(set_authzid) - p_authzid = &authzid; - if(set_password) - p_password = &password; - if(set_realm) - p_realm = &realm; - - c->setClientParams(p_username, p_authzid, p_password, p_realm); - } - - void start() - { - op = OpStart; - first = true; - - if(server) - { - QCA_logTextMessage(QString("sasl[%1]: c->startServer()").arg(q->objectName()), Logger::Information); - c->startServer(server_realm, disableServerSendLast); - } - else - { - QCA_logTextMessage(QString("sasl[%1]: c->startClient()").arg(q->objectName()), Logger::Information); - c->startClient(mechlist, allowClientSendFirst); - } - } - - void putServerFirstStep(const QString &mech, const QByteArray *clientInit) - { - if(op != -1) - return; - - QCA_logTextMessage(QString("sasl[%1]: c->serverFirstStep()").arg(q->objectName()), Logger::Information); - op = OpServerFirstStep; - c->serverFirstStep(mech, clientInit); - } - - void putStep(const QByteArray &stepData) - { - if(op != -1) - return; - - QCA_logTextMessage(QString("sasl[%1]: c->nextStep()").arg(q->objectName()), Logger::Information); - op = OpNextStep; - c->nextStep(stepData); - } - - void tryAgain() - { - if(op != -1) - return; - - QCA_logTextMessage(QString("sasl[%1]: c->tryAgain()").arg(q->objectName()), Logger::Information); - op = OpTryAgain; - c->tryAgain(); - } - - void processNextAction() - { - if(actionQueue.isEmpty()) - { - if(need_update) - update(); - return; - } - - Action a = actionQueue.takeFirst(); - - // set up for the next one, if necessary - if(!actionQueue.isEmpty() || need_update) - { - if(!actionTrigger.isActive()) - actionTrigger.start(); - } - - if(a.type == Action::ClientStarted) - { - emit q->clientStarted(a.haveInit, a.stepData); - } - else if(a.type == Action::NextStep) - { - emit q->nextStep(a.stepData); - } - else if(a.type == Action::Authenticated) - { - authed = true; - - // write any app data waiting during authentication - if(!out.isEmpty()) - { - need_update = true; - if(!actionTrigger.isActive()) - actionTrigger.start(); - } - - QCA_logTextMessage(QString("sasl[%1]: authenticated").arg(q->objectName()), Logger::Information); - emit q->authenticated(); - } - else if(a.type == Action::ReadyRead) - { - emit q->readyRead(); - } - else if(a.type == Action::ReadyReadOutgoing) - { - emit q->readyReadOutgoing(); - } - } - - void update() - { - // defer writes while authenticating - if(!authed) - { - QCA_logTextMessage(QString("sasl[%1]: ignoring update while not yet authenticated").arg(q->objectName()), Logger::Information); - return; - } - - if(!actionQueue.isEmpty()) - { - QCA_logTextMessage(QString("sasl[%1]: ignoring update while processing actions").arg(q->objectName()), Logger::Information); - need_update = true; - return; - } - - // only allow one operation at a time - if(op != -1) - { - QCA_logTextMessage(QString("sasl[%1]: ignoring update while operation active").arg(q->objectName()), Logger::Information); - need_update = true; - return; - } - - need_update = false; - - QCA_logTextMessage(QString("sasl[%1]: c->update()").arg(q->objectName()), Logger::Information); - op = OpUpdate; - out_pending += out.size(); - c->update(from_net, out); - from_net.clear(); - out.clear(); - } + enum { + OpStart, + OpServerFirstStep, + OpNextStep, + OpTryAgain, + OpUpdate + }; + + class Action + { + public: + enum Type { + ClientStarted, + NextStep, + Authenticated, + ReadyRead, + ReadyReadOutgoing + }; + + int type; + QByteArray stepData; + bool haveInit; + + Action(int _type) : type(_type) + { + } + + Action(int _type, const QByteArray &_stepData) : type(_type), stepData(_stepData) + { + } + + Action(int _type, bool _haveInit, const QByteArray &_stepData) : type(_type), stepData(_stepData), haveInit(_haveInit) + { + } + }; + + SASL *q; + SASLContext *c; + + // persistent settings (survives ResetSessionAndData) + AuthFlags auth_flags; + int ssfmin, ssfmax; + QString ext_authid; + int ext_ssf; + bool localSet, remoteSet; + SASLContext::HostPort local, remote; + bool set_username, set_authzid, set_password, set_realm; + QString username, authzid, realm; + SecureArray password; + + // session + bool server; + QStringList mechlist; + QString server_realm; + bool allowClientSendFirst; + bool disableServerSendLast; + SafeTimer actionTrigger; + int op; + QList actionQueue; + bool need_update; + bool first; + bool authed; + + // data (survives ResetSession) + QString mech; // selected mech + Error errorCode; + + // stream i/o + QByteArray in, out; + QByteArray to_net, from_net; + int out_pending; + int to_net_encoded; + LayerTracker layer; + + Private(SASL *_q) : QObject(_q), q(_q), actionTrigger(this) + { + c = 0; + set_username = false; + set_authzid = false; + set_password = false; + set_realm = false; + + connect(&actionTrigger, SIGNAL(timeout()), SLOT(doNextAction())); + actionTrigger.setSingleShot(true); + + reset(ResetAll); + + c = static_cast(q->context()); + + // parent the context to us, so that moveToThread works + c->setParent(this); + + connect(c, SIGNAL(resultsReady()), SLOT(sasl_resultsReady())); + } + + ~Private() + { + // context is owned by Algorithm, unparent so we don't double-delete + c->setParent(0); + } + + void reset(ResetMode mode) + { + if (c) { + c->reset(); + } + + server = false; + mechlist.clear(); + server_realm = QString(); + allowClientSendFirst = false; + disableServerSendLast = true; + actionTrigger.stop(); + op = -1; + actionQueue.clear(); + need_update = false; + first = false; + authed = false; + + out.clear(); + out_pending = 0; + + if (mode >= ResetSessionAndData) { + mech = QString(); + errorCode = (SASL::Error) - 1; + + in.clear(); + to_net.clear(); + from_net.clear(); + to_net_encoded = 0; + layer.reset(); + } + + if (mode >= ResetAll) { + auth_flags = SASL::AuthFlagsNone; + ssfmin = 0; + ssfmax = 0; + ext_authid = QString(); + ext_ssf = 0; + localSet = false; + remoteSet = false; + local = SASLContext::HostPort(); + remote = SASLContext::HostPort(); + + set_username = false; + username = QString(); + set_authzid = false; + authzid = QString(); + set_password = false; + password = SecureArray(); + set_realm = false; + realm = QString(); + } + } + + void setup(const QString &service, const QString &host) + { + c->setup(service, host, localSet ? &local : 0, remoteSet ? &remote : 0, ext_authid, ext_ssf); + c->setConstraints(auth_flags, ssfmin, ssfmax); + + QString *p_username = 0; + QString *p_authzid = 0; + SecureArray *p_password = 0; + QString *p_realm = 0; + + if (set_username) { + p_username = &username; + } + if (set_authzid) { + p_authzid = &authzid; + } + if (set_password) { + p_password = &password; + } + if (set_realm) { + p_realm = &realm; + } + + c->setClientParams(p_username, p_authzid, p_password, p_realm); + } + + void start() + { + op = OpStart; + first = true; + + if (server) { + QCA_logTextMessage(QString("sasl[%1]: c->startServer()").arg(q->objectName()), Logger::Information); + c->startServer(server_realm, disableServerSendLast); + } else { + QCA_logTextMessage(QString("sasl[%1]: c->startClient()").arg(q->objectName()), Logger::Information); + c->startClient(mechlist, allowClientSendFirst); + } + } + + void putServerFirstStep(const QString &mech, const QByteArray *clientInit) + { + if (op != -1) { + return; + } + + QCA_logTextMessage(QString("sasl[%1]: c->serverFirstStep()").arg(q->objectName()), Logger::Information); + op = OpServerFirstStep; + c->serverFirstStep(mech, clientInit); + } + + void putStep(const QByteArray &stepData) + { + if (op != -1) { + return; + } + + QCA_logTextMessage(QString("sasl[%1]: c->nextStep()").arg(q->objectName()), Logger::Information); + op = OpNextStep; + c->nextStep(stepData); + } + + void tryAgain() + { + if (op != -1) { + return; + } + + QCA_logTextMessage(QString("sasl[%1]: c->tryAgain()").arg(q->objectName()), Logger::Information); + op = OpTryAgain; + c->tryAgain(); + } + + void processNextAction() + { + if (actionQueue.isEmpty()) { + if (need_update) { + update(); + } + return; + } + + Action a = actionQueue.takeFirst(); + + // set up for the next one, if necessary + if (!actionQueue.isEmpty() || need_update) { + if (!actionTrigger.isActive()) { + actionTrigger.start(); + } + } + + if (a.type == Action::ClientStarted) { + emit q->clientStarted(a.haveInit, a.stepData); + } else if (a.type == Action::NextStep) { + emit q->nextStep(a.stepData); + } else if (a.type == Action::Authenticated) { + authed = true; + + // write any app data waiting during authentication + if (!out.isEmpty()) { + need_update = true; + if (!actionTrigger.isActive()) { + actionTrigger.start(); + } + } + + QCA_logTextMessage(QString("sasl[%1]: authenticated").arg(q->objectName()), Logger::Information); + emit q->authenticated(); + } else if (a.type == Action::ReadyRead) { + emit q->readyRead(); + } else if (a.type == Action::ReadyReadOutgoing) { + emit q->readyReadOutgoing(); + } + } + + void update() + { + // defer writes while authenticating + if (!authed) { + QCA_logTextMessage(QString("sasl[%1]: ignoring update while not yet authenticated").arg(q->objectName()), Logger::Information); + return; + } + + if (!actionQueue.isEmpty()) { + QCA_logTextMessage(QString("sasl[%1]: ignoring update while processing actions").arg(q->objectName()), Logger::Information); + need_update = true; + return; + } + + // only allow one operation at a time + if (op != -1) { + QCA_logTextMessage(QString("sasl[%1]: ignoring update while operation active").arg(q->objectName()), Logger::Information); + need_update = true; + return; + } + + need_update = false; + + QCA_logTextMessage(QString("sasl[%1]: c->update()").arg(q->objectName()), Logger::Information); + op = OpUpdate; + out_pending += out.size(); + c->update(from_net, out); + from_net.clear(); + out.clear(); + } private slots: - void sasl_resultsReady() - { - QCA_logTextMessage(QString("sasl[%1]: c->resultsReady()").arg(q->objectName()), Logger::Information); - - int last_op = op; - op = -1; - - SASLContext::Result r = c->result(); - - if(last_op == OpStart) - { - if(server) - { - if(r != SASLContext::Success) - { - errorCode = SASL::ErrorInit; - emit q->error(); - return; - } - - emit q->serverStarted(); - return; - } - else // client - { - mech = c->mech(); - - // fall into this logic - last_op = OpTryAgain; - } - } - else if(last_op == OpServerFirstStep) - { - // fall into this logic - last_op = OpTryAgain; - } - else if(last_op == OpNextStep) - { - // fall into this logic - last_op = OpTryAgain; - } - - if(last_op == OpTryAgain) - { - if(server) - { - if(r == SASLContext::Continue) - { - emit q->nextStep(c->stepData()); - return; - } - else if(r == SASLContext::AuthCheck) - { - emit q->authCheck(c->username(), c->authzid()); - return; - } - else if(r == SASLContext::Success) - { - if(!disableServerSendLast) - actionQueue += Action(Action::NextStep, c->stepData()); - - actionQueue += Action(Action::Authenticated); - - processNextAction(); - return; - } - else // error - { - errorCode = SASL::ErrorHandshake; - emit q->error(); - return; - } - } - else // client - { - if(first) - { - if(r == SASLContext::Error) - { - if(first) - errorCode = SASL::ErrorInit; - else - errorCode = SASL::ErrorHandshake; - emit q->error(); - return; - } - else if(r == SASLContext::Params) - { - Params np = c->clientParams(); - emit q->needParams(np); - return; - } - - first = false; - actionQueue += Action(Action::ClientStarted, c->haveClientInit(), c->stepData()); - if(r == SASLContext::Success) - actionQueue += Action(Action::Authenticated); - - processNextAction(); - return; - } - else - { - if(r == SASLContext::Error) - { - errorCode = ErrorHandshake; - emit q->error(); - return; - } - else if(r == SASLContext::Params) - { - Params np = c->clientParams(); - emit q->needParams(np); - return; - } - else if(r == SASLContext::Continue) - { - emit q->nextStep(c->stepData()); - return; - } - else if(r == SASLContext::Success) - { - actionQueue += Action(Action::NextStep, c->stepData()); - actionQueue += Action(Action::Authenticated); - - processNextAction(); - return; - } - } - } - } - else if(last_op == OpUpdate) - { - if(r != SASLContext::Success) - { - errorCode = ErrorCrypt; - emit q->error(); - return; - } - - QByteArray c_to_net = c->to_net(); - QByteArray c_to_app = c->to_app(); - int enc = -1; - if(!c_to_net.isEmpty()) - enc = c->encoded(); - - bool io_pending = false; - if(!c_to_net.isEmpty()) - out_pending -= enc; - - if(out_pending > 0) - io_pending = true; - - if(!out.isEmpty()) - io_pending = true; - - to_net += c_to_net; - in += c_to_app; - to_net_encoded += enc; - - if(!c_to_net.isEmpty()) - actionQueue += Action(Action::ReadyReadOutgoing); - - if(!c_to_app.isEmpty()) - actionQueue += Action(Action::ReadyRead); - - if(io_pending) - update(); - - processNextAction(); - return; - } - } - - void doNextAction() - { - processNextAction(); - } + void sasl_resultsReady() + { + QCA_logTextMessage(QString("sasl[%1]: c->resultsReady()").arg(q->objectName()), Logger::Information); + + int last_op = op; + op = -1; + + SASLContext::Result r = c->result(); + + if (last_op == OpStart) { + if (server) { + if (r != SASLContext::Success) { + errorCode = SASL::ErrorInit; + emit q->error(); + return; + } + + emit q->serverStarted(); + return; + } else { // client + mech = c->mech(); + + // fall into this logic + last_op = OpTryAgain; + } + } else if (last_op == OpServerFirstStep) { + // fall into this logic + last_op = OpTryAgain; + } else if (last_op == OpNextStep) { + // fall into this logic + last_op = OpTryAgain; + } + + if (last_op == OpTryAgain) { + if (server) { + if (r == SASLContext::Continue) { + emit q->nextStep(c->stepData()); + return; + } else if (r == SASLContext::AuthCheck) { + emit q->authCheck(c->username(), c->authzid()); + return; + } else if (r == SASLContext::Success) { + if (!disableServerSendLast) { + actionQueue += Action(Action::NextStep, c->stepData()); + } + + actionQueue += Action(Action::Authenticated); + + processNextAction(); + return; + } else { // error + errorCode = SASL::ErrorHandshake; + emit q->error(); + return; + } + } else { // client + if (first) { + if (r == SASLContext::Error) { + if (first) { + errorCode = SASL::ErrorInit; + } else { + errorCode = SASL::ErrorHandshake; + } + emit q->error(); + return; + } else if (r == SASLContext::Params) { + Params np = c->clientParams(); + emit q->needParams(np); + return; + } + + first = false; + actionQueue += Action(Action::ClientStarted, c->haveClientInit(), c->stepData()); + if (r == SASLContext::Success) { + actionQueue += Action(Action::Authenticated); + } + + processNextAction(); + return; + } else { + if (r == SASLContext::Error) { + errorCode = ErrorHandshake; + emit q->error(); + return; + } else if (r == SASLContext::Params) { + Params np = c->clientParams(); + emit q->needParams(np); + return; + } else if (r == SASLContext::Continue) { + emit q->nextStep(c->stepData()); + return; + } else if (r == SASLContext::Success) { + actionQueue += Action(Action::NextStep, c->stepData()); + actionQueue += Action(Action::Authenticated); + + processNextAction(); + return; + } + } + } + } else if (last_op == OpUpdate) { + if (r != SASLContext::Success) { + errorCode = ErrorCrypt; + emit q->error(); + return; + } + + QByteArray c_to_net = c->to_net(); + QByteArray c_to_app = c->to_app(); + int enc = -1; + if (!c_to_net.isEmpty()) { + enc = c->encoded(); + } + + bool io_pending = false; + if (!c_to_net.isEmpty()) { + out_pending -= enc; + } + + if (out_pending > 0) { + io_pending = true; + } + + if (!out.isEmpty()) { + io_pending = true; + } + + to_net += c_to_net; + in += c_to_app; + to_net_encoded += enc; + + if (!c_to_net.isEmpty()) { + actionQueue += Action(Action::ReadyReadOutgoing); + } + + if (!c_to_app.isEmpty()) { + actionQueue += Action(Action::ReadyRead); + } + + if (io_pending) { + update(); + } + + processNextAction(); + return; + } + } + + void doNextAction() + { + processNextAction(); + } }; SASL::SASL(QObject *parent, const QString &provider) -:SecureLayer(parent), Algorithm("sasl", provider) + : SecureLayer(parent), Algorithm("sasl", provider) { - d = new Private(this); + d = new Private(this); } SASL::~SASL() { - delete d; + delete d; } void SASL::reset() { - d->reset(ResetAll); + d->reset(ResetAll); } SASL::Error SASL::errorCode() const { - return d->errorCode; + return d->errorCode; } SASL::AuthCondition SASL::authCondition() const { - return d->c->authCondition(); + return d->c->authCondition(); } void SASL::setConstraints(AuthFlags f, SecurityLevel s) { - int min = 0; - if(s == SL_Integrity) - min = 1; - else if(s == SL_Export) - min = 56; - else if(s == SL_Baseline) - min = 128; - else if(s == SL_High) - min = 192; - else if(s == SL_Highest) - min = 256; + int min = 0; + if (s == SL_Integrity) { + min = 1; + } else if (s == SL_Export) { + min = 56; + } else if (s == SL_Baseline) { + min = 128; + } else if (s == SL_High) { + min = 192; + } else if (s == SL_Highest) { + min = 256; + } - setConstraints(f, min, 256); + setConstraints(f, min, 256); } void SASL::setConstraints(AuthFlags f, int minSSF, int maxSSF) { - d->auth_flags = f; + d->auth_flags = f; - d->ssfmin = minSSF; - d->ssfmax = maxSSF; + d->ssfmin = minSSF; + d->ssfmax = maxSSF; } void SASL::setExternalAuthId(const QString &authid) { - d->ext_authid = authid; + d->ext_authid = authid; } void SASL::setExternalSSF(int strength) { - d->ext_ssf = strength; + d->ext_ssf = strength; } void SASL::setLocalAddress(const QString &addr, quint16 port) { - d->localSet = true; - d->local.addr = addr; - d->local.port = port; + d->localSet = true; + d->local.addr = addr; + d->local.port = port; } void SASL::setRemoteAddress(const QString &addr, quint16 port) { - d->remoteSet = true; - d->remote.addr = addr; - d->remote.port = port; + d->remoteSet = true; + d->remote.addr = addr; + d->remote.port = port; } void SASL::startClient(const QString &service, const QString &host, const QStringList &mechlist, ClientSendMode mode) { - d->reset(ResetSessionAndData); - d->setup(service, host); - d->server = false; - d->mechlist = mechlist; - d->allowClientSendFirst = (mode == AllowClientSendFirst); - d->start(); + d->reset(ResetSessionAndData); + d->setup(service, host); + d->server = false; + d->mechlist = mechlist; + d->allowClientSendFirst = (mode == AllowClientSendFirst); + d->start(); } void SASL::startServer(const QString &service, const QString &host, const QString &realm, ServerSendMode mode) { - d->reset(ResetSessionAndData); - d->setup(service, host); - d->server = true; - d->server_realm = realm; - d->disableServerSendLast = (mode == DisableServerSendLast); - d->start(); + d->reset(ResetSessionAndData); + d->setup(service, host); + d->server = true; + d->server_realm = realm; + d->disableServerSendLast = (mode == DisableServerSendLast); + d->start(); } void SASL::putServerFirstStep(const QString &mech) { - d->putServerFirstStep(mech, 0); + d->putServerFirstStep(mech, 0); } void SASL::putServerFirstStep(const QString &mech, const QByteArray &clientInit) { - d->putServerFirstStep(mech, &clientInit); + d->putServerFirstStep(mech, &clientInit); } void SASL::putStep(const QByteArray &stepData) { - d->putStep(stepData); + d->putStep(stepData); } void SASL::setUsername(const QString &user) { - d->set_username = true; - d->username = user; - d->c->setClientParams(&user, 0, 0, 0); + d->set_username = true; + d->username = user; + d->c->setClientParams(&user, 0, 0, 0); } void SASL::setAuthzid(const QString &authzid) { - d->set_authzid = true; - d->authzid = authzid; - d->c->setClientParams(0, &authzid, 0, 0); + d->set_authzid = true; + d->authzid = authzid; + d->c->setClientParams(0, &authzid, 0, 0); } void SASL::setPassword(const SecureArray &pass) { - d->set_password = true; - d->password = pass; - d->c->setClientParams(0, 0, &pass, 0); + d->set_password = true; + d->password = pass; + d->c->setClientParams(0, 0, &pass, 0); } void SASL::setRealm(const QString &realm) { - d->set_realm = true; - d->realm = realm; - d->c->setClientParams(0, 0, 0, &realm); + d->set_realm = true; + d->realm = realm; + d->c->setClientParams(0, 0, 0, &realm); } void SASL::continueAfterParams() { - d->tryAgain(); + d->tryAgain(); } void SASL::continueAfterAuthCheck() { - d->tryAgain(); + d->tryAgain(); } QString SASL::mechanism() const { - return d->mech; + return d->mech; } QStringList SASL::mechanismList() const { - return d->c->mechlist(); + return d->c->mechlist(); } QStringList SASL::realmList() const { - return d->c->realmlist(); + return d->c->realmlist(); } int SASL::ssf() const { - return d->c->ssf(); + return d->c->ssf(); } int SASL::bytesAvailable() const { - return d->in.size(); + return d->in.size(); } int SASL::bytesOutgoingAvailable() const { - return d->to_net.size(); + return d->to_net.size(); } void SASL::write(const QByteArray &a) { - d->out.append(a); - d->layer.addPlain(a.size()); - d->update(); + d->out.append(a); + d->layer.addPlain(a.size()); + d->update(); } QByteArray SASL::read() { - QByteArray a = d->in; - d->in.clear(); - return a; + QByteArray a = d->in; + d->in.clear(); + return a; } void SASL::writeIncoming(const QByteArray &a) { - d->from_net.append(a); - d->update(); + d->from_net.append(a); + d->update(); } QByteArray SASL::readOutgoing(int *plainBytes) { - QByteArray a = d->to_net; - d->to_net.clear(); - if(plainBytes) - *plainBytes = d->to_net_encoded; - d->layer.specifyEncoded(a.size(), d->to_net_encoded); - d->to_net_encoded = 0; - return a; + QByteArray a = d->to_net; + d->to_net.clear(); + if (plainBytes) { + *plainBytes = d->to_net_encoded; + } + d->layer.specifyEncoded(a.size(), d->to_net_encoded); + d->to_net_encoded = 0; + return a; } int SASL::convertBytesWritten(qint64 bytes) { - return d->layer.finished(bytes); + return d->layer.finished(bytes); } } diff --git a/src/qca_securemessage.cpp b/src/qca_securemessage.cpp --- a/src/qca_securemessage.cpp +++ b/src/qca_securemessage.cpp @@ -25,7 +25,8 @@ #include "qca_safeobj.h" #include "qca_safetimer.h" -namespace QCA { +namespace QCA +{ Provider::Context *getContext(const QString &type, const QString &provider); @@ -35,581 +36,577 @@ class SecureMessageKey::Private : public QSharedData { public: - SecureMessageKey::Type type; - PGPKey pgp_pub, pgp_sec; - CertificateChain cert_pub; - PrivateKey cert_sec; - - Private() - { - type = SecureMessageKey::None; - } - - // set the proper type, and reset the opposite data structures if needed - void ensureType(SecureMessageKey::Type t) - { - // if we were non-null and changed, we may need to reset some things - if(type != SecureMessageKey::None && t != type) - { - if(type == SecureMessageKey::X509) - { - cert_pub = CertificateChain(); - cert_sec = PrivateKey(); - } - else if(type == SecureMessageKey::PGP) - { - pgp_pub = PGPKey(); - pgp_sec = PGPKey(); - } - } - type = t; - } + SecureMessageKey::Type type; + PGPKey pgp_pub, pgp_sec; + CertificateChain cert_pub; + PrivateKey cert_sec; + + Private() + { + type = SecureMessageKey::None; + } + + // set the proper type, and reset the opposite data structures if needed + void ensureType(SecureMessageKey::Type t) + { + // if we were non-null and changed, we may need to reset some things + if (type != SecureMessageKey::None && t != type) { + if (type == SecureMessageKey::X509) { + cert_pub = CertificateChain(); + cert_sec = PrivateKey(); + } else if (type == SecureMessageKey::PGP) { + pgp_pub = PGPKey(); + pgp_sec = PGPKey(); + } + } + type = t; + } }; SecureMessageKey::SecureMessageKey() -:d(new Private) + : d(new Private) { } SecureMessageKey::SecureMessageKey(const SecureMessageKey &from) -:d(from.d) + : d(from.d) { } SecureMessageKey::~SecureMessageKey() { } -SecureMessageKey & SecureMessageKey::operator=(const SecureMessageKey &from) +SecureMessageKey &SecureMessageKey::operator=(const SecureMessageKey &from) { - d = from.d; - return *this; + d = from.d; + return *this; } bool SecureMessageKey::isNull() const { - return (d->type == None); + return (d->type == None); } SecureMessageKey::Type SecureMessageKey::type() const { - return d->type; + return d->type; } PGPKey SecureMessageKey::pgpPublicKey() const { - return d->pgp_pub; + return d->pgp_pub; } PGPKey SecureMessageKey::pgpSecretKey() const { - return d->pgp_sec; + return d->pgp_sec; } void SecureMessageKey::setPGPPublicKey(const PGPKey &pub) { - d->ensureType(SecureMessageKey::PGP); - d->pgp_pub = pub; + d->ensureType(SecureMessageKey::PGP); + d->pgp_pub = pub; } void SecureMessageKey::setPGPSecretKey(const PGPKey &sec) { - d->ensureType(SecureMessageKey::PGP); - Q_ASSERT(sec.isSecret()); - d->pgp_sec = sec; + d->ensureType(SecureMessageKey::PGP); + Q_ASSERT(sec.isSecret()); + d->pgp_sec = sec; } CertificateChain SecureMessageKey::x509CertificateChain() const { - return d->cert_pub; + return d->cert_pub; } PrivateKey SecureMessageKey::x509PrivateKey() const { - return d->cert_sec; + return d->cert_sec; } void SecureMessageKey::setX509CertificateChain(const CertificateChain &c) { - d->ensureType(SecureMessageKey::X509); - d->cert_pub = c; + d->ensureType(SecureMessageKey::X509); + d->cert_pub = c; } void SecureMessageKey::setX509PrivateKey(const PrivateKey &k) { - d->ensureType(SecureMessageKey::X509); - d->cert_sec = k; + d->ensureType(SecureMessageKey::X509); + d->cert_sec = k; } void SecureMessageKey::setX509KeyBundle(const KeyBundle &kb) { - setX509CertificateChain(kb.certificateChain()); - setX509PrivateKey(kb.privateKey()); + setX509CertificateChain(kb.certificateChain()); + setX509PrivateKey(kb.privateKey()); } bool SecureMessageKey::havePrivate() const { - if(d->type == SecureMessageKey::PGP && !d->pgp_sec.isNull()) - return true; - else if(d->type == SecureMessageKey::X509 && !d->cert_sec.isNull()) - return true; - return false; + if (d->type == SecureMessageKey::PGP && !d->pgp_sec.isNull()) { + return true; + } else if (d->type == SecureMessageKey::X509 && !d->cert_sec.isNull()) { + return true; + } + return false; } QString SecureMessageKey::name() const { - if(d->type == SecureMessageKey::PGP && !d->pgp_pub.isNull()) - return d->pgp_pub.primaryUserId(); - else if(d->type == SecureMessageKey::X509 && !d->cert_pub.isEmpty()) - return d->cert_pub.primary().commonName(); - else - return QString(); + if (d->type == SecureMessageKey::PGP && !d->pgp_pub.isNull()) { + return d->pgp_pub.primaryUserId(); + } else if (d->type == SecureMessageKey::X509 && !d->cert_pub.isEmpty()) { + return d->cert_pub.primary().commonName(); + } else { + return QString(); + } } //---------------------------------------------------------------------------- // SecureMessageSignature //---------------------------------------------------------------------------- class SecureMessageSignature::Private : public QSharedData { public: - SecureMessageSignature::IdentityResult r; - Validity v; - SecureMessageKey key; - QDateTime ts; - - Private() - { - r = SecureMessageSignature::NoKey; - v = ErrorValidityUnknown; - } + SecureMessageSignature::IdentityResult r; + Validity v; + SecureMessageKey key; + QDateTime ts; + + Private() + { + r = SecureMessageSignature::NoKey; + v = ErrorValidityUnknown; + } }; SecureMessageSignature::SecureMessageSignature() -:d(new Private) + : d(new Private) { } SecureMessageSignature::SecureMessageSignature(IdentityResult r, Validity v, const SecureMessageKey &key, const QDateTime &ts) -:d(new Private) + : d(new Private) { - d->r = r; - d->v = v; - d->key = key; - d->ts = ts; + d->r = r; + d->v = v; + d->key = key; + d->ts = ts; } SecureMessageSignature::SecureMessageSignature(const SecureMessageSignature &from) -:d(from.d) + : d(from.d) { } SecureMessageSignature::~SecureMessageSignature() { } -SecureMessageSignature & SecureMessageSignature::operator=(const SecureMessageSignature &from) +SecureMessageSignature &SecureMessageSignature::operator=(const SecureMessageSignature &from) { - d = from.d; - return *this; + d = from.d; + return *this; } SecureMessageSignature::IdentityResult SecureMessageSignature::identityResult() const { - return d->r; + return d->r; } Validity SecureMessageSignature::keyValidity() const { - return d->v; + return d->v; } SecureMessageKey SecureMessageSignature::key() const { - return d->key; + return d->key; } QDateTime SecureMessageSignature::timestamp() const { - return d->ts; + return d->ts; } //---------------------------------------------------------------------------- // SecureMessage //---------------------------------------------------------------------------- -enum ResetMode -{ - ResetSession = 0, - ResetSessionAndData = 1, - ResetAll = 2 +enum ResetMode { + ResetSession = 0, + ResetSessionAndData = 1, + ResetAll = 2 }; class SecureMessage::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - SecureMessage *q; - MessageContext *c; - SecureMessageSystem *system; - - bool bundleSigner, smime; - SecureMessage::Format format; - SecureMessageKeyList to; - SecureMessageKeyList from; - - QByteArray in; - bool success; - SecureMessage::Error errorCode; - QByteArray detachedSig; - QString hashName; - SecureMessageSignatureList signers; - QString dtext; - - QList bytesWrittenArgs; - SafeTimer readyReadTrigger, bytesWrittenTrigger, finishedTrigger; - - Private(SecureMessage *_q) : readyReadTrigger(this), bytesWrittenTrigger(this), finishedTrigger(this) - { - q = _q; - c = 0; - system = 0; - - readyReadTrigger.setSingleShot(true); - bytesWrittenTrigger.setSingleShot(true); - finishedTrigger.setSingleShot(true); - connect(&readyReadTrigger, SIGNAL(timeout()), SLOT(t_readyRead())); - connect(&bytesWrittenTrigger, SIGNAL(timeout()), SLOT(t_bytesWritten())); - connect(&finishedTrigger, SIGNAL(timeout()), SLOT(t_finished())); - - reset(ResetAll); - } - - void init() - { - connect(c, SIGNAL(updated()), SLOT(updated())); - } - - void reset(ResetMode mode) - { - if(c) - c->reset(); - - bytesWrittenArgs.clear(); - readyReadTrigger.stop(); - bytesWrittenTrigger.stop(); - finishedTrigger.stop(); - - if(mode >= ResetSessionAndData) - { - in.clear(); - success = false; - errorCode = SecureMessage::ErrorUnknown; - detachedSig.clear(); - hashName = QString(); - signers.clear(); - } - - if(mode >= ResetAll) - { - bundleSigner = true; - format = SecureMessage::Binary; - to.clear(); - from.clear(); - } - } + SecureMessage *q; + MessageContext *c; + SecureMessageSystem *system; + + bool bundleSigner, smime; + SecureMessage::Format format; + SecureMessageKeyList to; + SecureMessageKeyList from; + + QByteArray in; + bool success; + SecureMessage::Error errorCode; + QByteArray detachedSig; + QString hashName; + SecureMessageSignatureList signers; + QString dtext; + + QList bytesWrittenArgs; + SafeTimer readyReadTrigger, bytesWrittenTrigger, finishedTrigger; + + Private(SecureMessage *_q) : readyReadTrigger(this), bytesWrittenTrigger(this), finishedTrigger(this) + { + q = _q; + c = 0; + system = 0; + + readyReadTrigger.setSingleShot(true); + bytesWrittenTrigger.setSingleShot(true); + finishedTrigger.setSingleShot(true); + connect(&readyReadTrigger, SIGNAL(timeout()), SLOT(t_readyRead())); + connect(&bytesWrittenTrigger, SIGNAL(timeout()), SLOT(t_bytesWritten())); + connect(&finishedTrigger, SIGNAL(timeout()), SLOT(t_finished())); + + reset(ResetAll); + } + + void init() + { + connect(c, SIGNAL(updated()), SLOT(updated())); + } + + void reset(ResetMode mode) + { + if (c) { + c->reset(); + } + + bytesWrittenArgs.clear(); + readyReadTrigger.stop(); + bytesWrittenTrigger.stop(); + finishedTrigger.stop(); + + if (mode >= ResetSessionAndData) { + in.clear(); + success = false; + errorCode = SecureMessage::ErrorUnknown; + detachedSig.clear(); + hashName = QString(); + signers.clear(); + } + + if (mode >= ResetAll) { + bundleSigner = true; + format = SecureMessage::Binary; + to.clear(); + from.clear(); + } + } public slots: - void updated() - { - bool sig_read = false; - bool sig_written = false; - bool sig_done = false; - int written = 0; - { - QByteArray a = c->read(); - if(!a.isEmpty()) - { - sig_read = true; - in.append(a); - } - - int x = c->written(); - if(x > 0) - { - sig_written = true; - written = x; - } - } - - if(c->finished()) - { - sig_done = true; - - success = c->success(); - errorCode = c->errorCode(); - dtext = c->diagnosticText(); - if(success) - { - detachedSig = c->signature(); - hashName = c->hashName(); - signers = c->signers(); - } - reset(ResetSession); - } - - if(sig_read) - readyReadTrigger.start(); - if(sig_written) - { - bytesWrittenArgs += written; - bytesWrittenTrigger.start(); - } - if(sig_done) - finishedTrigger.start(); - } - - void t_readyRead() - { - emit q->readyRead(); - } - - void t_bytesWritten() - { - emit q->bytesWritten(bytesWrittenArgs.takeFirst()); - } - - void t_finished() - { - emit q->finished(); - } + void updated() + { + bool sig_read = false; + bool sig_written = false; + bool sig_done = false; + int written = 0; + { + QByteArray a = c->read(); + if (!a.isEmpty()) { + sig_read = true; + in.append(a); + } + + int x = c->written(); + if (x > 0) { + sig_written = true; + written = x; + } + } + + if (c->finished()) { + sig_done = true; + + success = c->success(); + errorCode = c->errorCode(); + dtext = c->diagnosticText(); + if (success) { + detachedSig = c->signature(); + hashName = c->hashName(); + signers = c->signers(); + } + reset(ResetSession); + } + + if (sig_read) { + readyReadTrigger.start(); + } + if (sig_written) { + bytesWrittenArgs += written; + bytesWrittenTrigger.start(); + } + if (sig_done) { + finishedTrigger.start(); + } + } + + void t_readyRead() + { + emit q->readyRead(); + } + + void t_bytesWritten() + { + emit q->bytesWritten(bytesWrittenArgs.takeFirst()); + } + + void t_finished() + { + emit q->finished(); + } }; SecureMessage::SecureMessage(SecureMessageSystem *system) { - d = new Private(this); - d->system = system; - d->c = static_cast(d->system->context())->createMessage(); - change(d->c); - d->init(); + d = new Private(this); + d->system = system; + d->c = static_cast(d->system->context())->createMessage(); + change(d->c); + d->init(); } SecureMessage::~SecureMessage() { - delete d; + delete d; } SecureMessage::Type SecureMessage::type() const { - return d->c->type(); + return d->c->type(); } bool SecureMessage::canSignMultiple() const { - return d->c->canSignMultiple(); + return d->c->canSignMultiple(); } bool SecureMessage::canClearsign() const { - return (type() == OpenPGP); + return (type() == OpenPGP); } bool SecureMessage::canSignAndEncrypt() const { - return (type() == OpenPGP); + return (type() == OpenPGP); } void SecureMessage::reset() { - d->reset(ResetAll); + d->reset(ResetAll); } bool SecureMessage::bundleSignerEnabled() const { - return d->bundleSigner; + return d->bundleSigner; } bool SecureMessage::smimeAttributesEnabled() const { - return d->smime; + return d->smime; } SecureMessage::Format SecureMessage::format() const { - return d->format; + return d->format; } SecureMessageKeyList SecureMessage::recipientKeys() const { - return d->to; + return d->to; } SecureMessageKeyList SecureMessage::signerKeys() const { - return d->from; + return d->from; } void SecureMessage::setBundleSignerEnabled(bool b) { - d->bundleSigner = b; + d->bundleSigner = b; } void SecureMessage::setSMIMEAttributesEnabled(bool b) { - d->smime = b; + d->smime = b; } void SecureMessage::setFormat(Format f) { - d->format = f; + d->format = f; } void SecureMessage::setRecipient(const SecureMessageKey &key) { - d->to = SecureMessageKeyList() << key; + d->to = SecureMessageKeyList() << key; } void SecureMessage::setRecipients(const SecureMessageKeyList &keys) { - d->to = keys; + d->to = keys; } void SecureMessage::setSigner(const SecureMessageKey &key) { - d->from = SecureMessageKeyList() << key; + d->from = SecureMessageKeyList() << key; } void SecureMessage::setSigners(const SecureMessageKeyList &keys) { - d->from = keys; + d->from = keys; } void SecureMessage::startEncrypt() { - d->reset(ResetSessionAndData); - d->c->setupEncrypt(d->to); - d->c->start(d->format, MessageContext::Encrypt); + d->reset(ResetSessionAndData); + d->c->setupEncrypt(d->to); + d->c->start(d->format, MessageContext::Encrypt); } void SecureMessage::startDecrypt() { - d->reset(ResetSessionAndData); - d->c->start(d->format, MessageContext::Decrypt); + d->reset(ResetSessionAndData); + d->c->start(d->format, MessageContext::Decrypt); } void SecureMessage::startSign(SignMode m) { - d->reset(ResetSessionAndData); - d->c->setupSign(d->from, m, d->bundleSigner, d->smime); - d->c->start(d->format, MessageContext::Sign); + d->reset(ResetSessionAndData); + d->c->setupSign(d->from, m, d->bundleSigner, d->smime); + d->c->start(d->format, MessageContext::Sign); } void SecureMessage::startVerify(const QByteArray &sig) { - d->reset(ResetSessionAndData); - if(!sig.isEmpty()) - d->c->setupVerify(sig); - d->c->start(d->format, MessageContext::Verify); + d->reset(ResetSessionAndData); + if (!sig.isEmpty()) { + d->c->setupVerify(sig); + } + d->c->start(d->format, MessageContext::Verify); } void SecureMessage::startSignAndEncrypt() { - d->reset(ResetSessionAndData); - d->c->setupEncrypt(d->to); - d->c->setupSign(d->from, Message, d->bundleSigner, d->smime); - d->c->start(d->format, MessageContext::SignAndEncrypt); + d->reset(ResetSessionAndData); + d->c->setupEncrypt(d->to); + d->c->setupSign(d->from, Message, d->bundleSigner, d->smime); + d->c->start(d->format, MessageContext::SignAndEncrypt); } void SecureMessage::update(const QByteArray &in) { - d->c->update(in); + d->c->update(in); } QByteArray SecureMessage::read() { - QByteArray a = d->in; - d->in.clear(); - return a; + QByteArray a = d->in; + d->in.clear(); + return a; } int SecureMessage::bytesAvailable() const { - return d->in.size(); + return d->in.size(); } void SecureMessage::end() { - d->c->end(); + d->c->end(); } bool SecureMessage::waitForFinished(int msecs) { - d->c->waitForFinished(msecs); - d->updated(); - return d->success; + d->c->waitForFinished(msecs); + d->updated(); + return d->success; } bool SecureMessage::success() const { - return d->success; + return d->success; } SecureMessage::Error SecureMessage::errorCode() const { - return d->errorCode; + return d->errorCode; } QByteArray SecureMessage::signature() const { - return d->detachedSig; + return d->detachedSig; } QString SecureMessage::hashName() const { - return d->hashName; + return d->hashName; } bool SecureMessage::wasSigned() const { - return !d->signers.isEmpty(); + return !d->signers.isEmpty(); } bool SecureMessage::verifySuccess() const { - // if we're not done or there were no signers, then return false - if(!d->success || d->signers.isEmpty()) - return false; + // if we're not done or there were no signers, then return false + if (!d->success || d->signers.isEmpty()) { + return false; + } - // make sure all signers have a valid signature - for(int n = 0; n < d->signers.count(); ++n) - { - if(d->signers[n].identityResult() != SecureMessageSignature::Valid) - return false; - } - return true; + // make sure all signers have a valid signature + for (int n = 0; n < d->signers.count(); ++n) { + if (d->signers[n].identityResult() != SecureMessageSignature::Valid) { + return false; + } + } + return true; } SecureMessageSignature SecureMessage::signer() const { - if(d->signers.isEmpty()) - return SecureMessageSignature(); + if (d->signers.isEmpty()) { + return SecureMessageSignature(); + } - return d->signers.first(); + return d->signers.first(); } SecureMessageSignatureList SecureMessage::signers() const { - return d->signers; + return d->signers; } QString SecureMessage::diagnosticText() const { - return d->dtext; + return d->dtext; } //---------------------------------------------------------------------------- // SecureMessageSystem //---------------------------------------------------------------------------- SecureMessageSystem::SecureMessageSystem(QObject *parent, const QString &type, const QString &provider) -:QObject(parent), Algorithm(type, provider) + : QObject(parent), Algorithm(type, provider) { } @@ -621,7 +618,7 @@ // OpenPGP //---------------------------------------------------------------------------- OpenPGP::OpenPGP(QObject *parent, const QString &provider) -:SecureMessageSystem(parent, "openpgp", provider) + : SecureMessageSystem(parent, "openpgp", provider) { } @@ -635,52 +632,52 @@ class CMS::Private { public: - CertificateCollection trusted, untrusted; - SecureMessageKeyList privateKeys; + CertificateCollection trusted, untrusted; + SecureMessageKeyList privateKeys; }; CMS::CMS(QObject *parent, const QString &provider) -:SecureMessageSystem(parent, "cms", provider) + : SecureMessageSystem(parent, "cms", provider) { - d = new Private; + d = new Private; } CMS::~CMS() { - delete d; + delete d; } CertificateCollection CMS::trustedCertificates() const { - return d->trusted; + return d->trusted; } CertificateCollection CMS::untrustedCertificates() const { - return d->untrusted; + return d->untrusted; } SecureMessageKeyList CMS::privateKeys() const { - return d->privateKeys; + return d->privateKeys; } void CMS::setTrustedCertificates(const CertificateCollection &trusted) { - d->trusted = trusted; - static_cast(context())->setTrustedCertificates(trusted); + d->trusted = trusted; + static_cast(context())->setTrustedCertificates(trusted); } void CMS::setUntrustedCertificates(const CertificateCollection &untrusted) { - d->untrusted = untrusted; - static_cast(context())->setUntrustedCertificates(untrusted); + d->untrusted = untrusted; + static_cast(context())->setUntrustedCertificates(untrusted); } void CMS::setPrivateKeys(const SecureMessageKeyList &keys) { - d->privateKeys = keys; - static_cast(context())->setPrivateKeys(keys); + d->privateKeys = keys; + static_cast(context())->setPrivateKeys(keys); } } diff --git a/src/qca_systemstore.h b/src/qca_systemstore.h --- a/src/qca_systemstore.h +++ b/src/qca_systemstore.h @@ -26,7 +26,8 @@ #include "qca_cert.h" -namespace QCA { +namespace QCA +{ bool qca_have_systemstore(); CertificateCollection qca_get_systemstore(const QString &provider); diff --git a/src/qca_systemstore_flatfile.cpp b/src/qca_systemstore_flatfile.cpp --- a/src/qca_systemstore_flatfile.cpp +++ b/src/qca_systemstore_flatfile.cpp @@ -22,17 +22,18 @@ #include -namespace QCA { +namespace QCA +{ bool qca_have_systemstore() { - QFile f(QCA_SYSTEMSTORE_PATH); - return f.open(QFile::ReadOnly); + QFile f(QCA_SYSTEMSTORE_PATH); + return f.open(QFile::ReadOnly); } CertificateCollection qca_get_systemstore(const QString &provider) { - return CertificateCollection::fromFlatTextFile(QCA_SYSTEMSTORE_PATH, 0, provider); + return CertificateCollection::fromFlatTextFile(QCA_SYSTEMSTORE_PATH, 0, provider); } } diff --git a/src/qca_systemstore_mac.cpp b/src/qca_systemstore_mac.cpp --- a/src/qca_systemstore_mac.cpp +++ b/src/qca_systemstore_mac.cpp @@ -23,32 +23,34 @@ #include #include -namespace QCA { +namespace QCA +{ bool qca_have_systemstore() { - return true; + return true; } CertificateCollection qca_get_systemstore(const QString &provider) { - CertificateCollection col; - CFArrayRef anchors; - if(SecTrustCopyAnchorCertificates(&anchors) != 0) - return col; - for(int n = 0; n < CFArrayGetCount(anchors); ++n) - { - SecCertificateRef cr = (SecCertificateRef)CFArrayGetValueAtIndex(anchors, n); - CFDataRef derRef = SecCertificateCopyData(cr); - QByteArray der((const char *)CFDataGetBytePtr(derRef), CFDataGetLength(derRef)); - CFRelease(derRef); + CertificateCollection col; + CFArrayRef anchors; + if (SecTrustCopyAnchorCertificates(&anchors) != 0) { + return col; + } + for (int n = 0; n < CFArrayGetCount(anchors); ++n) { + SecCertificateRef cr = (SecCertificateRef)CFArrayGetValueAtIndex(anchors, n); + CFDataRef derRef = SecCertificateCopyData(cr); + QByteArray der((const char *)CFDataGetBytePtr(derRef), CFDataGetLength(derRef)); + CFRelease(derRef); - Certificate cert = Certificate::fromDER(der, 0, provider); - if(!cert.isNull()) - col.addCertificate(cert); - } - CFRelease(anchors); - return col; + Certificate cert = Certificate::fromDER(der, 0, provider); + if (!cert.isNull()) { + col.addCertificate(cert); + } + } + CFRelease(anchors); + return col; } } diff --git a/src/qca_systemstore_win.cpp b/src/qca_systemstore_win.cpp --- a/src/qca_systemstore_win.cpp +++ b/src/qca_systemstore_win.cpp @@ -26,48 +26,52 @@ #include #include -namespace QCA { +namespace QCA +{ bool qca_have_systemstore() { - bool ok = false; - HCERTSTORE hSystemStore; - hSystemStore = CertOpenSystemStoreA(0, "ROOT"); - if(hSystemStore) - ok = true; - CertCloseStore(hSystemStore, 0); - return ok; + bool ok = false; + HCERTSTORE hSystemStore; + hSystemStore = CertOpenSystemStoreA(0, "ROOT"); + if (hSystemStore) { + ok = true; + } + CertCloseStore(hSystemStore, 0); + return ok; } CertificateCollection qca_get_systemstore(const QString &provider) { - CertificateCollection col; - HCERTSTORE hSystemStore; - hSystemStore = CertOpenSystemStoreA(0, "ROOT"); - if(!hSystemStore) - return col; - PCCERT_CONTEXT pc = NULL; - while(1) - { - pc = CertFindCertificateInStore( - hSystemStore, - X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, - 0, - CERT_FIND_ANY, - NULL, - pc); - if(!pc) - break; - int size = pc->cbCertEncoded; - QByteArray der(size, 0); - memcpy(der.data(), pc->pbCertEncoded, size); + CertificateCollection col; + HCERTSTORE hSystemStore; + hSystemStore = CertOpenSystemStoreA(0, "ROOT"); + if (!hSystemStore) { + return col; + } + PCCERT_CONTEXT pc = NULL; + while (1) { + pc = CertFindCertificateInStore( + hSystemStore, + X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + 0, + CERT_FIND_ANY, + NULL, + pc); + if (!pc) { + break; + } + int size = pc->cbCertEncoded; + QByteArray der(size, 0); + memcpy(der.data(), pc->pbCertEncoded, size); - Certificate cert = Certificate::fromDER(der, 0, provider); - if(!cert.isNull()) - col.addCertificate(cert); - } - CertCloseStore(hSystemStore, 0); - return col; + Certificate cert = Certificate::fromDER(der, 0, provider); + if (!cert.isNull()) { + col.addCertificate(cert); + } + } + CertCloseStore(hSystemStore, 0); + return col; } } diff --git a/src/qca_textfilter.cpp b/src/qca_textfilter.cpp --- a/src/qca_textfilter.cpp +++ b/src/qca_textfilter.cpp @@ -21,497 +21,484 @@ #include "qca_textfilter.h" -namespace QCA { +namespace QCA +{ //---------------------------------------------------------------------------- // TextFilter //---------------------------------------------------------------------------- TextFilter::TextFilter(Direction dir) { - setup(dir); + setup(dir); } void TextFilter::setup(Direction dir) { - _dir = dir; + _dir = dir; } Direction TextFilter::direction() const { - return _dir; + return _dir; } MemoryRegion TextFilter::encode(const MemoryRegion &a) { - setup(Encode); - return process(a); + setup(Encode); + return process(a); } MemoryRegion TextFilter::decode(const MemoryRegion &a) { - setup(Decode); - return process(a); + setup(Decode); + return process(a); } QString TextFilter::arrayToString(const MemoryRegion &a) { - return QString::fromLatin1(encode(a).toByteArray()); + return QString::fromLatin1(encode(a).toByteArray()); } MemoryRegion TextFilter::stringToArray(const QString &s) { - if(s.isEmpty()) - return MemoryRegion(); - return decode(s.toLatin1()); + if (s.isEmpty()) { + return MemoryRegion(); + } + return decode(s.toLatin1()); } QString TextFilter::encodeString(const QString &s) { - return arrayToString(s.toUtf8()); + return arrayToString(s.toUtf8()); } QString TextFilter::decodeString(const QString &s) { - return QString::fromUtf8(stringToArray(s).toByteArray()); + return QString::fromUtf8(stringToArray(s).toByteArray()); } //---------------------------------------------------------------------------- // Hex //---------------------------------------------------------------------------- static int enhex(uchar c) { - if(c < 10) - return c + '0'; - else if(c < 16) - return c - 10 + 'a'; - else - return -1; + if (c < 10) { + return c + '0'; + } else if (c < 16) { + return c - 10 + 'a'; + } else { + return -1; + } } static int dehex(char c) { - if(c >= 'a' && c <= 'f') - return c - 'a' + 10; - else if(c >= 'A' && c <= 'F') - return c - 'A' + 10; - else if(c >= '0' && c <= '9') - return c - '0'; - else - return -1; + if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } else if (c >= '0' && c <= '9') { + return c - '0'; + } else { + return -1; + } } Hex::Hex(Direction dir) -:TextFilter(dir) + : TextFilter(dir) { - clear(); + clear(); } void Hex::clear() { - partial = false; - _ok = true; + partial = false; + _ok = true; } MemoryRegion Hex::update(const MemoryRegion &m) { - QByteArray a = m.toByteArray(); - if(_dir == Encode) - { - QByteArray out(a.size() * 2, 0); - int at = 0; - int c; - for(int n = 0; n < (int)a.size(); ++n) - { - uchar lo = (uchar)a[n] & 0x0f; - uchar hi = (uchar)a[n] >> 4; - c = enhex(hi); - if(c == -1) - { - _ok = false; - break; - } - out[at++] = (char)c; - c = enhex(lo); - if(c == -1) - { - _ok = false; - break; - } - out[at++] = (char)c; - } - if(!_ok) - return MemoryRegion(); - - return out; - } - else - { - uchar lo = 0; - uchar hi = 0; - bool flag = false; - if(partial) - { - hi = val; - flag = true; - } - - QByteArray out(a.size() / 2, 0); - int at = 0; - int c; - for(int n = 0; n < (int)a.size(); ++n) - { - c = dehex((char)a[n]); - if(c == -1) - { - _ok = false; - break; - } - if(flag) - { - lo = (uchar)c; - uchar full = ((hi & 0x0f) << 4) + (lo & 0x0f); - out[at++] = full; - flag = false; - } - else - { - hi = (uchar)c; - flag = true; - } - } - if(!_ok) - return MemoryRegion(); - - if(flag) - { - val = hi; - partial = true; - } - return out; - } + QByteArray a = m.toByteArray(); + if (_dir == Encode) { + QByteArray out(a.size() * 2, 0); + int at = 0; + int c; + for (int n = 0; n < (int)a.size(); ++n) { + uchar lo = (uchar)a[n] & 0x0f; + uchar hi = (uchar)a[n] >> 4; + c = enhex(hi); + if (c == -1) { + _ok = false; + break; + } + out[at++] = (char)c; + c = enhex(lo); + if (c == -1) { + _ok = false; + break; + } + out[at++] = (char)c; + } + if (!_ok) { + return MemoryRegion(); + } + + return out; + } else { + uchar lo = 0; + uchar hi = 0; + bool flag = false; + if (partial) { + hi = val; + flag = true; + } + + QByteArray out(a.size() / 2, 0); + int at = 0; + int c; + for (int n = 0; n < (int)a.size(); ++n) { + c = dehex((char)a[n]); + if (c == -1) { + _ok = false; + break; + } + if (flag) { + lo = (uchar)c; + uchar full = ((hi & 0x0f) << 4) + (lo & 0x0f); + out[at++] = full; + flag = false; + } else { + hi = (uchar)c; + flag = true; + } + } + if (!_ok) { + return MemoryRegion(); + } + + if (flag) { + val = hi; + partial = true; + } + return out; + } } MemoryRegion Hex::final() { - if(partial) - _ok = false; - return MemoryRegion(); + if (partial) { + _ok = false; + } + return MemoryRegion(); } bool Hex::ok() const { - return _ok; + return _ok; } //---------------------------------------------------------------------------- // Base64 //---------------------------------------------------------------------------- Base64::Base64(Direction dir) -:TextFilter(dir) + : TextFilter(dir) { - _lb_enabled = false; - _lb_column = 76; + _lb_enabled = false; + _lb_column = 76; } void Base64::clear() { - partial.resize(0); - _ok = true; - col = 0; + partial.resize(0); + _ok = true; + col = 0; } bool Base64::lineBreaksEnabled() const { - return _lb_enabled; + return _lb_enabled; } int Base64::lineBreaksColumn() const { - return _lb_column; + return _lb_column; } void Base64::setLineBreaksEnabled(bool b) { - _lb_enabled = b; + _lb_enabled = b; } void Base64::setLineBreaksColumn(int column) { - if(column > 0) - _lb_column = column; - else - _lb_column = 76; + if (column > 0) { + _lb_column = column; + } else { + _lb_column = 76; + } } static QByteArray b64encode(const QByteArray &s) { - int i; - int len = s.size(); - static char tbl[] = - "ABCDEFGH" - "IJKLMNOP" - "QRSTUVWX" - "YZabcdef" - "ghijklmn" - "opqrstuv" - "wxyz0123" - "456789+/" - "="; - int a, b, c; - - QByteArray p((len + 2) / 3 * 4, 0); - int at = 0; - for(i = 0; i < len; i += 3) - { - a = ((unsigned char)s[i] & 3) << 4; - if(i + 1 < len) - { - a += (unsigned char)s[i + 1] >> 4; - b = ((unsigned char)s[i + 1] & 0xf) << 2; - if(i + 2 < len) - { - b += (unsigned char)s[i + 2] >> 6; - c = (unsigned char)s[i + 2] & 0x3f; - } - else - c = 64; - } - else - b = c = 64; - - p[at++] = tbl[(unsigned char)s[i] >> 2]; - p[at++] = tbl[a]; - p[at++] = tbl[b]; - p[at++] = tbl[c]; - } - return p; + int i; + int len = s.size(); + static char tbl[] = + "ABCDEFGH" + "IJKLMNOP" + "QRSTUVWX" + "YZabcdef" + "ghijklmn" + "opqrstuv" + "wxyz0123" + "456789+/" + "="; + int a, b, c; + + QByteArray p((len + 2) / 3 * 4, 0); + int at = 0; + for (i = 0; i < len; i += 3) { + a = ((unsigned char)s[i] & 3) << 4; + if (i + 1 < len) { + a += (unsigned char)s[i + 1] >> 4; + b = ((unsigned char)s[i + 1] & 0xf) << 2; + if (i + 2 < len) { + b += (unsigned char)s[i + 2] >> 6; + c = (unsigned char)s[i + 2] & 0x3f; + } else { + c = 64; + } + } else { + b = c = 64; + } + + p[at++] = tbl[(unsigned char)s[i] >> 2]; + p[at++] = tbl[a]; + p[at++] = tbl[b]; + p[at++] = tbl[c]; + } + return p; } static QByteArray b64decode(const QByteArray &s, bool *ok) { - // -1 specifies invalid - // 64 specifies eof - // everything else specifies data - - static signed char tbl[] = - { - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, - 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, - 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, - -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, - 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - }; - - // return value - QByteArray p; - *ok = true; - - // this should be a multiple of 4 - int len = s.size(); - if(len % 4) - { - *ok = false; - return p; - } - - p.resize(len / 4 * 3); - - int i; - int at = 0; - - int a, b, c, d; - c = d = 0; - - for(i = 0; i < len; i += 4) - { - a = tbl[(int)s[i]]; - b = tbl[(int)s[i + 1]]; - c = tbl[(int)s[i + 2]]; - d = tbl[(int)s[i + 3]]; - if((a == 64 || b == 64) || (a < 0 || b < 0 || c < 0 || d < 0)) - { - p.resize(0); - *ok = false; - return p; - } - p[at++] = ((a & 0x3F) << 2) | ((b >> 4) & 0x03); - p[at++] = ((b & 0x0F) << 4) | ((c >> 2) & 0x0F); - p[at++] = ((c & 0x03) << 6) | ((d >> 0) & 0x3F); - } - - if(c & 64) - p.resize(at - 2); - else if(d & 64) - p.resize(at - 1); - - return p; + // -1 specifies invalid + // 64 specifies eof + // everything else specifies data + + static signed char tbl[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + + // return value + QByteArray p; + *ok = true; + + // this should be a multiple of 4 + int len = s.size(); + if (len % 4) { + *ok = false; + return p; + } + + p.resize(len / 4 * 3); + + int i; + int at = 0; + + int a, b, c, d; + c = d = 0; + + for (i = 0; i < len; i += 4) { + a = tbl[(int)s[i]]; + b = tbl[(int)s[i + 1]]; + c = tbl[(int)s[i + 2]]; + d = tbl[(int)s[i + 3]]; + if ((a == 64 || b == 64) || (a < 0 || b < 0 || c < 0 || d < 0)) { + p.resize(0); + *ok = false; + return p; + } + p[at++] = ((a & 0x3F) << 2) | ((b >> 4) & 0x03); + p[at++] = ((b & 0x0F) << 4) | ((c >> 2) & 0x0F); + p[at++] = ((c & 0x03) << 6) | ((d >> 0) & 0x3F); + } + + if (c & 64) { + p.resize(at - 2); + } else if (d & 64) { + p.resize(at - 1); + } + + return p; } static int findLF(const QByteArray &in, int offset) { - for(int n = offset; n < in.size(); ++n) - { - if(in[n] == '\n') - return n; - } - return -1; + for (int n = offset; n < in.size(); ++n) { + if (in[n] == '\n') { + return n; + } + } + return -1; } static QByteArray insert_linebreaks(const QByteArray &s, int *col, int lfAt) { - QByteArray out = s; + QByteArray out = s; - int needed = (out.size() + *col) / lfAt; // how many newlines needed? - if(needed > 0) - { - int firstlen = lfAt - *col; // length of first chunk - int at = firstlen + (lfAt * (needed - 1)); // position of last newline - int lastlen = out.size() - at; // length of last chunk + int needed = (out.size() + *col) / lfAt; // how many newlines needed? + if (needed > 0) { + int firstlen = lfAt - *col; // length of first chunk + int at = firstlen + (lfAt * (needed - 1)); // position of last newline + int lastlen = out.size() - at; // length of last chunk - //printf("size=%d,needed=%d,firstlen=%d,at=%d,lastlen=%d\n", out.size(), needed, firstlen, at, lastlen); + //printf("size=%d,needed=%d,firstlen=%d,at=%d,lastlen=%d\n", out.size(), needed, firstlen, at, lastlen); - // make room - out.resize(out.size() + needed); + // make room + out.resize(out.size() + needed); - // move backwards - for(int n = 0; n < needed; ++n) - { - char *p = out.data() + at; - int len; - if(n == 0) - len = lastlen; - else - len = lfAt; - memmove(p + needed - n, p, len); - p[needed - n - 1] = '\n'; - at -= lfAt; - } + // move backwards + for (int n = 0; n < needed; ++n) { + char *p = out.data() + at; + int len; + if (n == 0) { + len = lastlen; + } else { + len = lfAt; + } + memmove(p + needed - n, p, len); + p[needed - n - 1] = '\n'; + at -= lfAt; + } - *col = lastlen; - } - else - *col += out.size(); + *col = lastlen; + } else { + *col += out.size(); + } - return out; + return out; } static QByteArray remove_linebreaks(const QByteArray &s) { - QByteArray out = s; - - int removed = 0; - int at = findLF(out, 0); - while(at != -1) - { - int next = findLF(out, at + 1); - int len; - if(next != -1) - len = next - at; - else - len = out.size() - at; - - if(len > 1) - { - char *p = out.data() + at; - memmove(p - removed, p + 1, len - 1); - } - ++removed; - at = next; - } - out.resize(out.size() - removed); - - return out; + QByteArray out = s; + + int removed = 0; + int at = findLF(out, 0); + while (at != -1) { + int next = findLF(out, at + 1); + int len; + if (next != -1) { + len = next - at; + } else { + len = out.size() - at; + } + + if (len > 1) { + char *p = out.data() + at; + memmove(p - removed, p + 1, len - 1); + } + ++removed; + at = next; + } + out.resize(out.size() - removed); + + return out; } static void appendArray(QByteArray *a, const QByteArray &b) { - a->append(b); + a->append(b); } MemoryRegion Base64::update(const MemoryRegion &m) { - QByteArray in; - if(_dir == Decode && _lb_enabled) - in = remove_linebreaks(m.toByteArray()); - else - in = m.toByteArray(); - - if(in.isEmpty()) - return MemoryRegion(); - - int chunk; - if(_dir == Encode) - chunk = 3; - else - chunk = 4; - - int size = partial.size() + in.size(); - if(size < chunk) - { - appendArray(&partial, in); - return MemoryRegion(); - } - - int eat = size % chunk; - - // s = partial + a - eat - QByteArray s(partial.size() + in.size() - eat, 0); - memcpy(s.data(), partial.data(), partial.size()); - memcpy(s.data() + partial.size(), in.data(), in.size() - eat); - - partial.resize(eat); - memcpy(partial.data(), in.data() + in.size() - eat, eat); - - if(_dir == Encode) - { - if(_lb_enabled) - return insert_linebreaks(b64encode(s), &col, _lb_column); - else - return b64encode(s); - } - else - { - bool ok; - QByteArray out = b64decode(s, &ok); - if(!ok) - _ok = false; - return out; - } + QByteArray in; + if (_dir == Decode && _lb_enabled) { + in = remove_linebreaks(m.toByteArray()); + } else { + in = m.toByteArray(); + } + + if (in.isEmpty()) { + return MemoryRegion(); + } + + int chunk; + if (_dir == Encode) { + chunk = 3; + } else { + chunk = 4; + } + + int size = partial.size() + in.size(); + if (size < chunk) { + appendArray(&partial, in); + return MemoryRegion(); + } + + int eat = size % chunk; + + // s = partial + a - eat + QByteArray s(partial.size() + in.size() - eat, 0); + memcpy(s.data(), partial.data(), partial.size()); + memcpy(s.data() + partial.size(), in.data(), in.size() - eat); + + partial.resize(eat); + memcpy(partial.data(), in.data() + in.size() - eat, eat); + + if (_dir == Encode) { + if (_lb_enabled) { + return insert_linebreaks(b64encode(s), &col, _lb_column); + } else { + return b64encode(s); + } + } else { + bool ok; + QByteArray out = b64decode(s, &ok); + if (!ok) { + _ok = false; + } + return out; + } } MemoryRegion Base64::final() { - if(_dir == Encode) - { - if(_lb_enabled) - return insert_linebreaks(b64encode(partial), &col, _lb_column); - else - return b64encode(partial); - } - else - { - bool ok; - QByteArray out = b64decode(partial, &ok); - if(!ok) - _ok = false; - return out; - } + if (_dir == Encode) { + if (_lb_enabled) { + return insert_linebreaks(b64encode(partial), &col, _lb_column); + } else { + return b64encode(partial); + } + } else { + bool ok; + QByteArray out = b64decode(partial, &ok); + if (!ok) { + _ok = false; + } + return out; + } } bool Base64::ok() const { - return _ok; + return _ok; } } diff --git a/src/qca_tools.cpp b/src/qca_tools.cpp --- a/src/qca_tools.cpp +++ b/src/qca_tools.cpp @@ -29,30 +29,30 @@ #endif #include "botantools/botantools.h" -namespace QCA { +namespace QCA +{ static bool can_lock() { #ifdef Q_OS_UNIX - bool ok = false; + bool ok = false; #ifdef MLOCK_NOT_VOID_PTR # define MLOCK_TYPE char * # define MLOCK_TYPE_CAST (MLOCK_TYPE) #else # define MLOCK_TYPE void * # define MLOCK_TYPE_CAST #endif - MLOCK_TYPE d = MLOCK_TYPE_CAST malloc(256); - if(mlock(d, 256) == 0) - { - munlock(d, 256); - ok = true; - } - free(d); - return ok; + MLOCK_TYPE d = MLOCK_TYPE_CAST malloc(256); + if (mlock(d, 256) == 0) { + munlock(d, 256); + ok = true; + } + free(d); + return ok; #else - return true; + return true; #endif } @@ -62,143 +62,131 @@ void botan_throw_abort() { - fprintf(stderr, "QCA: Exception from internal Botan\n"); - abort(); + fprintf(stderr, "QCA: Exception from internal Botan\n"); + abort(); } bool botan_init(int prealloc, bool mmap) { - // 64k minimum - if(prealloc < 64) - prealloc = 64; - - bool secmem = false; - - try - { - Botan::Builtin_Modules modules; - Botan::Library_State *libstate = new Botan::Library_State(modules.mutex_factory()); - libstate->prealloc_size = prealloc * 1024; - Botan::set_global_state(libstate); - Botan::global_state().load(modules); - - if(can_lock()) - { - Botan::global_state().set_default_allocator("locking"); - secmem = true; - } - else if(mmap) - { - Botan::global_state().set_default_allocator("mmap"); - secmem = true; - } - alloc = Botan::Allocator::get(true); - } - catch(std::exception &) - { - fprintf(stderr, "QCA: Error initializing internal Botan\n"); - abort(); - } - - return secmem; + // 64k minimum + if (prealloc < 64) { + prealloc = 64; + } + + bool secmem = false; + + try { + Botan::Builtin_Modules modules; + Botan::Library_State *libstate = new Botan::Library_State(modules.mutex_factory()); + libstate->prealloc_size = prealloc * 1024; + Botan::set_global_state(libstate); + Botan::global_state().load(modules); + + if (can_lock()) { + Botan::global_state().set_default_allocator("locking"); + secmem = true; + } else if (mmap) { + Botan::global_state().set_default_allocator("mmap"); + secmem = true; + } + alloc = Botan::Allocator::get(true); + } catch (std::exception &) { + fprintf(stderr, "QCA: Error initializing internal Botan\n"); + abort(); + } + + return secmem; } void botan_deinit() { - try - { - alloc = 0; - Botan::set_global_state(0); - } - catch(std::exception &) - { - botan_throw_abort(); - } + try { + alloc = 0; + Botan::set_global_state(0); + } catch (std::exception &) { + botan_throw_abort(); + } } void *botan_secure_alloc(int bytes) { - try - { - return alloc->allocate((Botan::u32bit)bytes); - } - catch(std::exception &) - { - botan_throw_abort(); - } - return 0; // never get here + try { + return alloc->allocate((Botan::u32bit)bytes); + } catch (std::exception &) { + botan_throw_abort(); + } + return 0; // never get here } void botan_secure_free(void *p, int bytes) { - try - { - alloc->deallocate(p, (Botan::u32bit)bytes); - } - catch(std::exception &) - { - botan_throw_abort(); - } + try { + alloc->deallocate(p, (Botan::u32bit)bytes); + } catch (std::exception &) { + botan_throw_abort(); + } } } // end namespace QCA void *qca_secure_alloc(int bytes) { - // allocate enough room to store a size value in front, return a pointer after it - char *c = (char *)QCA::botan_secure_alloc(bytes + sizeof(int)); - ((int *)c)[0] = bytes + sizeof(int); - return c + sizeof(int); + // allocate enough room to store a size value in front, return a pointer after it + char *c = (char *)QCA::botan_secure_alloc(bytes + sizeof(int)); + ((int *)c)[0] = bytes + sizeof(int); + return c + sizeof(int); } void qca_secure_free(void *p) { - // backtrack to read the size value - char *c = (char *)p; - c -= sizeof(int); - int bytes = ((int *)c)[0]; - QCA::botan_secure_free(c, bytes); + // backtrack to read the size value + char *c = (char *)p; + c -= sizeof(int); + int bytes = ((int *)c)[0]; + QCA::botan_secure_free(c, bytes); } void *qca_secure_realloc(void *p, int bytes) { - // if null, do a plain alloc (just like how realloc() works) - if(!p) - return qca_secure_alloc(bytes); + // if null, do a plain alloc (just like how realloc() works) + if (!p) { + return qca_secure_alloc(bytes); + } - // backtrack to read the size value - char *c = (char *)p; - c -= sizeof(int); - int oldsize = ((int *)c)[0] - sizeof(int); + // backtrack to read the size value + char *c = (char *)p; + c -= sizeof(int); + int oldsize = ((int *)c)[0] - sizeof(int); - // alloc the new chunk - char *new_p = (char *)qca_secure_alloc(bytes); - if(!new_p) - return 0; + // alloc the new chunk + char *new_p = (char *)qca_secure_alloc(bytes); + if (!new_p) { + return 0; + } - // move over the memory from the original block - memmove(new_p, p, qMin(oldsize, bytes)); + // move over the memory from the original block + memmove(new_p, p, qMin(oldsize, bytes)); - // free the original - qca_secure_free(p); + // free the original + qca_secure_free(p); - // done - return new_p; + // done + return new_p; } -namespace QCA { +namespace QCA +{ // secure or non-secure buffer, with trailing 0-byte. // buffer size of 0 is okay (sbuf/qbuf will be 0). -struct alloc_info -{ - bool sec; - char *data; - int size; - - // internal - Botan::SecureVector *sbuf; - QByteArray *qbuf; +struct alloc_info { + bool sec; + char *data; + int size; + + // internal + Botan::SecureVector *sbuf; + QByteArray *qbuf; }; // note: these functions don't return error if memory allocation/resizing @@ -222,163 +210,140 @@ bool ai_new(alloc_info *ai, int size, bool sec) { - if(size < 0) - return false; - - ai->size = size; - ai->sec = sec; - - if(size == 0) - { - ai->sbuf = 0; - ai->qbuf = 0; - ai->data = 0; - return true; - } - - if(sec) - { - try - { - ai->sbuf = new Botan::SecureVector((Botan::u32bit)size + 1); - } - catch(std::exception &) - { - botan_throw_abort(); - return false; // never get here - } - - (*(ai->sbuf))[size] = 0; - ai->qbuf = 0; - Botan::byte *bp = (Botan::byte *)(*(ai->sbuf)); - ai->data = (char *)bp; - } - else - { - ai->sbuf = 0; - ai->qbuf = new QByteArray(size, 0); - ai->data = ai->qbuf->data(); - } - - return true; + if (size < 0) { + return false; + } + + ai->size = size; + ai->sec = sec; + + if (size == 0) { + ai->sbuf = 0; + ai->qbuf = 0; + ai->data = 0; + return true; + } + + if (sec) { + try { + ai->sbuf = new Botan::SecureVector((Botan::u32bit)size + 1); + } catch (std::exception &) { + botan_throw_abort(); + return false; // never get here + } + + (*(ai->sbuf))[size] = 0; + ai->qbuf = 0; + Botan::byte *bp = (Botan::byte *)(*(ai->sbuf)); + ai->data = (char *)bp; + } else { + ai->sbuf = 0; + ai->qbuf = new QByteArray(size, 0); + ai->data = ai->qbuf->data(); + } + + return true; } bool ai_copy(alloc_info *ai, const alloc_info *from) { - ai->size = from->size; - ai->sec = from->sec; - - if(ai->size == 0) - { - ai->sbuf = 0; - ai->qbuf = 0; - ai->data = 0; - return true; - } - - if(ai->sec) - { - try - { - ai->sbuf = new Botan::SecureVector(*(from->sbuf)); - } - catch(std::exception &) - { - botan_throw_abort(); - return false; // never get here - } - - ai->qbuf = 0; - Botan::byte *bp = (Botan::byte *)(*(ai->sbuf)); - ai->data = (char *)bp; - } - else - { - ai->sbuf = 0; - ai->qbuf = new QByteArray(*(from->qbuf)); - ai->data = ai->qbuf->data(); - } - - return true; + ai->size = from->size; + ai->sec = from->sec; + + if (ai->size == 0) { + ai->sbuf = 0; + ai->qbuf = 0; + ai->data = 0; + return true; + } + + if (ai->sec) { + try { + ai->sbuf = new Botan::SecureVector(*(from->sbuf)); + } catch (std::exception &) { + botan_throw_abort(); + return false; // never get here + } + + ai->qbuf = 0; + Botan::byte *bp = (Botan::byte *)(*(ai->sbuf)); + ai->data = (char *)bp; + } else { + ai->sbuf = 0; + ai->qbuf = new QByteArray(*(from->qbuf)); + ai->data = ai->qbuf->data(); + } + + return true; } bool ai_resize(alloc_info *ai, int new_size) { - if(new_size < 0) - return false; - - // new size is empty - if(new_size == 0) - { - // we currently aren't empty - if(ai->size > 0) - { - if(ai->sec) - { - delete ai->sbuf; - ai->sbuf = 0; - } - else - { - delete ai->qbuf; - ai->qbuf = 0; - } - - ai->size = 0; - ai->data = 0; - } - - return true; - } - - if(ai->sec) - { - Botan::SecureVector *new_buf; - try - { - new_buf = new Botan::SecureVector((Botan::u32bit)new_size + 1); - } - catch(std::exception &) - { - botan_throw_abort(); - return false; // never get here - } - - Botan::byte *new_p = (Botan::byte *)(*new_buf); - if(ai->size > 0) - { - const Botan::byte *old_p = (const Botan::byte *)(*(ai->sbuf)); - memcpy(new_p, old_p, qMin(new_size, ai->size)); - delete ai->sbuf; - } - ai->sbuf = new_buf; - ai->size = new_size; - (*(ai->sbuf))[new_size] = 0; - ai->data = (char *)new_p; - } - else - { - if(ai->size > 0) - ai->qbuf->resize(new_size); - else - ai->qbuf = new QByteArray(new_size, 0); - - ai->size = new_size; - ai->data = ai->qbuf->data(); - } - - return true; + if (new_size < 0) { + return false; + } + + // new size is empty + if (new_size == 0) { + // we currently aren't empty + if (ai->size > 0) { + if (ai->sec) { + delete ai->sbuf; + ai->sbuf = 0; + } else { + delete ai->qbuf; + ai->qbuf = 0; + } + + ai->size = 0; + ai->data = 0; + } + + return true; + } + + if (ai->sec) { + Botan::SecureVector *new_buf; + try { + new_buf = new Botan::SecureVector((Botan::u32bit)new_size + 1); + } catch (std::exception &) { + botan_throw_abort(); + return false; // never get here + } + + Botan::byte *new_p = (Botan::byte *)(*new_buf); + if (ai->size > 0) { + const Botan::byte *old_p = (const Botan::byte *)(*(ai->sbuf)); + memcpy(new_p, old_p, qMin(new_size, ai->size)); + delete ai->sbuf; + } + ai->sbuf = new_buf; + ai->size = new_size; + (*(ai->sbuf))[new_size] = 0; + ai->data = (char *)new_p; + } else { + if (ai->size > 0) { + ai->qbuf->resize(new_size); + } else { + ai->qbuf = new QByteArray(new_size, 0); + } + + ai->size = new_size; + ai->data = ai->qbuf->data(); + } + + return true; } void ai_delete(alloc_info *ai) { - if(ai->size > 0) - { - if(ai->sec) - delete ai->sbuf; - else - delete ai->qbuf; - } + if (ai->size > 0) { + if (ai->sec) { + delete ai->sbuf; + } else { + delete ai->qbuf; + } + } } //---------------------------------------------------------------------------- @@ -389,613 +354,608 @@ class MemoryRegion::Private : public QSharedData { public: - alloc_info ai; - - Private(int size, bool sec) - { - ai_new(&ai, size, sec); - } - - Private(const QByteArray &from, bool sec) - { - ai_new(&ai, from.size(), sec); - memcpy(ai.data, from.data(), ai.size); - } - - Private(const Private &from) : QSharedData(from) - { - ai_copy(&ai, &from.ai); - } - - ~Private() - { - ai_delete(&ai); - } - - bool resize(int new_size) - { - return ai_resize(&ai, new_size); - } - - void setSecure(bool sec) - { - // if same mode, do nothing - if(ai.sec == sec) - return; - - alloc_info other; - ai_new(&other, ai.size, sec); - memcpy(other.data, ai.data, ai.size); - ai_delete(&ai); - ai = other; - } + alloc_info ai; + + Private(int size, bool sec) + { + ai_new(&ai, size, sec); + } + + Private(const QByteArray &from, bool sec) + { + ai_new(&ai, from.size(), sec); + memcpy(ai.data, from.data(), ai.size); + } + + Private(const Private &from) : QSharedData(from) + { + ai_copy(&ai, &from.ai); + } + + ~Private() + { + ai_delete(&ai); + } + + bool resize(int new_size) + { + return ai_resize(&ai, new_size); + } + + void setSecure(bool sec) + { + // if same mode, do nothing + if (ai.sec == sec) { + return; + } + + alloc_info other; + ai_new(&other, ai.size, sec); + memcpy(other.data, ai.data, ai.size); + ai_delete(&ai); + ai = other; + } }; MemoryRegion::MemoryRegion() -:_secure(false), d(0) + : _secure(false), d(0) { } MemoryRegion::MemoryRegion(const char *str) -:_secure(false), d(new Private(QByteArray::fromRawData(str, strlen(str)), false)) + : _secure(false), d(new Private(QByteArray::fromRawData(str, strlen(str)), false)) { } MemoryRegion::MemoryRegion(const QByteArray &from) -:_secure(false), d(new Private(from, false)) + : _secure(false), d(new Private(from, false)) { } MemoryRegion::MemoryRegion(const MemoryRegion &from) -:_secure(from._secure), d(from.d) + : _secure(from._secure), d(from.d) { } MemoryRegion::~MemoryRegion() { } -MemoryRegion & MemoryRegion::operator=(const MemoryRegion &from) +MemoryRegion &MemoryRegion::operator=(const MemoryRegion &from) { - _secure = from._secure; - d = from.d; - return *this; + _secure = from._secure; + d = from.d; + return *this; } -MemoryRegion & MemoryRegion::operator=(const QByteArray &from) +MemoryRegion &MemoryRegion::operator=(const QByteArray &from) { - set(from, false); - return *this; + set(from, false); + return *this; } bool MemoryRegion::isNull() const { - return (d ? false : true); + return (d ? false : true); } bool MemoryRegion::isSecure() const { - return _secure; + return _secure; } QByteArray MemoryRegion::toByteArray() const { - if(!d) - return QByteArray(); + if (!d) { + return QByteArray(); + } - if(d->ai.sec) - { - QByteArray buf(d->ai.size, 0); - memcpy(buf.data(), d->ai.data, d->ai.size); - return buf; - } - else - { - if(d->ai.size > 0) - return *(d->ai.qbuf); - else - return QByteArray((int)0, (char)0); - } + if (d->ai.sec) { + QByteArray buf(d->ai.size, 0); + memcpy(buf.data(), d->ai.data, d->ai.size); + return buf; + } else { + if (d->ai.size > 0) { + return *(d->ai.qbuf); + } else { + return QByteArray((int)0, (char)0); + } + } } MemoryRegion::MemoryRegion(bool secure) -:_secure(secure), d(0) + : _secure(secure), d(0) { } MemoryRegion::MemoryRegion(int size, bool secure) -:_secure(secure), d(new Private(size, secure)) + : _secure(secure), d(new Private(size, secure)) { } MemoryRegion::MemoryRegion(const QByteArray &from, bool secure) -:_secure(secure), d(new Private(from, secure)) + : _secure(secure), d(new Private(from, secure)) { } char *MemoryRegion::data() { - if(!d) - return blank; - return d->ai.data; + if (!d) { + return blank; + } + return d->ai.data; } const char *MemoryRegion::data() const { - if(!d) - return blank; - return d->ai.data; + if (!d) { + return blank; + } + return d->ai.data; } const char *MemoryRegion::constData() const { - if(!d) - return blank; - return d->ai.data; + if (!d) { + return blank; + } + return d->ai.data; } -char & MemoryRegion::at(int index) +char &MemoryRegion::at(int index) { - return *(d->ai.data + index); + return *(d->ai.data + index); } -const char & MemoryRegion::at(int index) const +const char &MemoryRegion::at(int index) const { - return *(d->ai.data + index); + return *(d->ai.data + index); } int MemoryRegion::size() const { - if(!d) - return 0; - return d->ai.size; + if (!d) { + return 0; + } + return d->ai.size; } bool MemoryRegion::isEmpty() const { - if(!d) - return true; - return (d->ai.size > 0 ? false : true); + if (!d) { + return true; + } + return (d->ai.size > 0 ? false : true); } bool MemoryRegion::resize(int size) { - if(!d) - { - d = new Private(size, _secure); - return true; - } + if (!d) { + d = new Private(size, _secure); + return true; + } - if(d->ai.size == size) - return true; + if (d->ai.size == size) { + return true; + } - return d->resize(size); + return d->resize(size); } void MemoryRegion::set(const QByteArray &from, bool secure) { - _secure = secure; + _secure = secure; - if(!from.isEmpty()) - d = new Private(from, secure); - else - d = new Private(0, secure); + if (!from.isEmpty()) { + d = new Private(from, secure); + } else { + d = new Private(0, secure); + } } void MemoryRegion::setSecure(bool secure) { - _secure = secure; + _secure = secure; - if(!d) - { - d = new Private(0, secure); - return; - } + if (!d) { + d = new Private(0, secure); + return; + } - d->setSecure(secure); + d->setSecure(secure); } //---------------------------------------------------------------------------- // SecureArray //---------------------------------------------------------------------------- SecureArray::SecureArray() -:MemoryRegion(true) + : MemoryRegion(true) { } SecureArray::SecureArray(int size, char ch) -:MemoryRegion(size, true) + : MemoryRegion(size, true) { - // ai_new fills with zeros for us - if(ch != 0) - fill(ch, size); + // ai_new fills with zeros for us + if (ch != 0) { + fill(ch, size); + } } SecureArray::SecureArray(const char *str) -:MemoryRegion(QByteArray::fromRawData(str, strlen(str)), true) + : MemoryRegion(QByteArray::fromRawData(str, strlen(str)), true) { } SecureArray::SecureArray(const QByteArray &a) -:MemoryRegion(a, true) + : MemoryRegion(a, true) { } SecureArray::SecureArray(const MemoryRegion &a) -:MemoryRegion(a) + : MemoryRegion(a) { - setSecure(true); + setSecure(true); } SecureArray::SecureArray(const SecureArray &from) -:MemoryRegion(from) + : MemoryRegion(from) { } SecureArray::~SecureArray() { } -SecureArray & SecureArray::operator=(const SecureArray &from) +SecureArray &SecureArray::operator=(const SecureArray &from) { - MemoryRegion::operator=(from); - return *this; + MemoryRegion::operator=(from); + return *this; } -SecureArray & SecureArray::operator=(const QByteArray &from) +SecureArray &SecureArray::operator=(const QByteArray &from) { - MemoryRegion::set(from, true); - return *this; + MemoryRegion::set(from, true); + return *this; } void SecureArray::clear() { - MemoryRegion::resize(0); + MemoryRegion::resize(0); } bool SecureArray::resize(int size) { - return MemoryRegion::resize(size); + return MemoryRegion::resize(size); } -char & SecureArray::operator[](int index) +char &SecureArray::operator[](int index) { - return at(index); + return at(index); } -const char & SecureArray::operator[](int index) const +const char &SecureArray::operator[](int index) const { - return at(index); + return at(index); } -char & SecureArray::at(int index) +char &SecureArray::at(int index) { - return MemoryRegion::at(index); + return MemoryRegion::at(index); } -const char & SecureArray::at(int index) const +const char &SecureArray::at(int index) const { - return MemoryRegion::at(index); + return MemoryRegion::at(index); } char *SecureArray::data() { - return MemoryRegion::data(); + return MemoryRegion::data(); } const char *SecureArray::data() const { - return MemoryRegion::data(); + return MemoryRegion::data(); } const char *SecureArray::constData() const { - return MemoryRegion::constData(); + return MemoryRegion::constData(); } int SecureArray::size() const { - return MemoryRegion::size(); + return MemoryRegion::size(); } bool SecureArray::isEmpty() const { - return MemoryRegion::isEmpty(); + return MemoryRegion::isEmpty(); } QByteArray SecureArray::toByteArray() const { - return MemoryRegion::toByteArray(); + return MemoryRegion::toByteArray(); } -SecureArray & SecureArray::append(const SecureArray &a) +SecureArray &SecureArray::append(const SecureArray &a) { - int oldsize = size(); - resize(oldsize + a.size()); - memcpy(data() + oldsize, a.data(), a.size()); - return *this; + int oldsize = size(); + resize(oldsize + a.size()); + memcpy(data() + oldsize, a.data(), a.size()); + return *this; } bool SecureArray::operator==(const MemoryRegion &other) const { - if(this == &other) - return true; - if(size() == other.size() && memcmp(data(), other.data(), size()) == 0) - return true; - return false; + if (this == &other) { + return true; + } + if (size() == other.size() && memcmp(data(), other.data(), size()) == 0) { + return true; + } + return false; } -SecureArray & SecureArray::operator+=(const SecureArray &a) +SecureArray &SecureArray::operator+=(const SecureArray &a) { - return append(a); + return append(a); } void SecureArray::fill(char fillChar, int fillToPosition) { - int len = (fillToPosition == -1) ? size() : qMin(fillToPosition, size()); - if(len > 0) - memset(data(), (int)fillChar, len); + int len = (fillToPosition == -1) ? size() : qMin(fillToPosition, size()); + if (len > 0) { + memset(data(), (int)fillChar, len); + } } void SecureArray::set(const SecureArray &from) { - *this = from; + *this = from; } void SecureArray::set(const QByteArray &from) { - *this = from; + *this = from; } const SecureArray operator+(const SecureArray &a, const SecureArray &b) { - SecureArray c = a; - return c.append(b); + SecureArray c = a; + return c.append(b); } //---------------------------------------------------------------------------- // BigInteger //---------------------------------------------------------------------------- static void negate_binary(char *a, int size) { - // negate = two's compliment + 1 - bool done = false; - for(int n = size - 1; n >= 0; --n) - { - a[n] = ~a[n]; - if(!done) - { - if((unsigned char)a[n] < 0xff) - { - ++a[n]; - done = true; - } - else - a[n] = 0; - } - } + // negate = two's compliment + 1 + bool done = false; + for (int n = size - 1; n >= 0; --n) { + a[n] = ~a[n]; + if (!done) { + if ((unsigned char)a[n] < 0xff) { + ++a[n]; + done = true; + } else { + a[n] = 0; + } + } + } } class BigInteger::Private : public QSharedData { public: - Botan::BigInt n; + Botan::BigInt n; }; BigInteger::BigInteger() { - d = new Private; + d = new Private; } BigInteger::BigInteger(int i) { - d = new Private; - if(i < 0) - { - d->n = Botan::BigInt(i * (-1)); - d->n.set_sign(Botan::BigInt::Negative); - } - else - { - d->n = Botan::BigInt(i); - d->n.set_sign(Botan::BigInt::Positive); - } + d = new Private; + if (i < 0) { + d->n = Botan::BigInt(i * (-1)); + d->n.set_sign(Botan::BigInt::Negative); + } else { + d->n = Botan::BigInt(i); + d->n.set_sign(Botan::BigInt::Positive); + } } BigInteger::BigInteger(const char *c) { - d = new Private; - fromString(QString(c)); + d = new Private; + fromString(QString(c)); } BigInteger::BigInteger(const QString &s) { - d = new Private; - fromString(s); + d = new Private; + fromString(s); } BigInteger::BigInteger(const SecureArray &a) { - d = new Private; - fromArray(a); + d = new Private; + fromArray(a); } BigInteger::BigInteger(const BigInteger &from) { - *this = from; + *this = from; } BigInteger::~BigInteger() { } -BigInteger & BigInteger::operator=(const BigInteger &from) +BigInteger &BigInteger::operator=(const BigInteger &from) { - d = from.d; - return *this; + d = from.d; + return *this; } -BigInteger & BigInteger::operator+=(const BigInteger &i) +BigInteger &BigInteger::operator+=(const BigInteger &i) { - d->n += i.d->n; - return *this; + d->n += i.d->n; + return *this; } -BigInteger & BigInteger::operator-=(const BigInteger &i) +BigInteger &BigInteger::operator-=(const BigInteger &i) { - d->n -= i.d->n; - return *this; + d->n -= i.d->n; + return *this; } -BigInteger & BigInteger::operator*=(const BigInteger &i) +BigInteger &BigInteger::operator*=(const BigInteger &i) { - d->n *= i.d->n; - return *this; + d->n *= i.d->n; + return *this; } -BigInteger & BigInteger::operator/=(const BigInteger &i) +BigInteger &BigInteger::operator/=(const BigInteger &i) { - try - { - d->n /= i.d->n; - } - catch(std::exception &) - { - fprintf(stderr, "QCA: Botan integer division error\n"); - abort(); - } - return *this; + try { + d->n /= i.d->n; + } catch (std::exception &) { + fprintf(stderr, "QCA: Botan integer division error\n"); + abort(); + } + return *this; } -BigInteger & BigInteger::operator%=(const BigInteger &i) +BigInteger &BigInteger::operator%=(const BigInteger &i) { - try - { - d->n %= i.d->n; - } - catch(std::exception &) - { - fprintf(stderr, "QCA: Botan integer division error\n"); - abort(); - } - return *this; + try { + d->n %= i.d->n; + } catch (std::exception &) { + fprintf(stderr, "QCA: Botan integer division error\n"); + abort(); + } + return *this; } -BigInteger & BigInteger::operator=(const QString &s) +BigInteger &BigInteger::operator=(const QString &s) { - fromString(s); - return *this; + fromString(s); + return *this; } int BigInteger::compare(const BigInteger &n) const { - return ( (d->n).cmp( n.d->n, true) ); + return ((d->n).cmp(n.d->n, true)); } -QTextStream &operator<<(QTextStream &stream, const BigInteger& b) +QTextStream &operator<<(QTextStream &stream, const BigInteger &b) { - stream << b.toString(); - return stream; + stream << b.toString(); + return stream; } SecureArray BigInteger::toArray() const { - int size = d->n.encoded_size(Botan::BigInt::Binary); + int size = d->n.encoded_size(Botan::BigInt::Binary); - // return at least 8 bits - if(size == 0) - { - SecureArray a(1); - a[0] = 0; - return a; - } + // return at least 8 bits + if (size == 0) { + SecureArray a(1); + a[0] = 0; + return a; + } - int offset = 0; - SecureArray a; + int offset = 0; + SecureArray a; - // make room for a sign bit if needed - if(d->n.get_bit((size * 8) - 1)) - { - ++size; - a.resize(size); - a[0] = 0; - ++offset; - } - else - a.resize(size); + // make room for a sign bit if needed + if (d->n.get_bit((size * 8) - 1)) { + ++size; + a.resize(size); + a[0] = 0; + ++offset; + } else { + a.resize(size); + } - Botan::BigInt::encode((Botan::byte *)a.data() + offset, d->n, Botan::BigInt::Binary); + Botan::BigInt::encode((Botan::byte *)a.data() + offset, d->n, Botan::BigInt::Binary); - if(d->n.is_negative()) - negate_binary(a.data(), a.size()); + if (d->n.is_negative()) { + negate_binary(a.data(), a.size()); + } - return a; + return a; } void BigInteger::fromArray(const SecureArray &_a) { - if(_a.isEmpty()) - { - d->n = Botan::BigInt(0); - return; - } - SecureArray a = _a; + if (_a.isEmpty()) { + d->n = Botan::BigInt(0); + return; + } + SecureArray a = _a; - Botan::BigInt::Sign sign = Botan::BigInt::Positive; - if(a[0] & 0x80) - sign = Botan::BigInt::Negative; + Botan::BigInt::Sign sign = Botan::BigInt::Positive; + if (a[0] & 0x80) { + sign = Botan::BigInt::Negative; + } - if(sign == Botan::BigInt::Negative) - negate_binary(a.data(), a.size()); + if (sign == Botan::BigInt::Negative) { + negate_binary(a.data(), a.size()); + } - d->n = Botan::BigInt::decode((const Botan::byte *)a.data(), a.size(), Botan::BigInt::Binary); - d->n.set_sign(sign); + d->n = Botan::BigInt::decode((const Botan::byte *)a.data(), a.size(), Botan::BigInt::Binary); + d->n.set_sign(sign); } QString BigInteger::toString() const { - QByteArray cs; - try - { - cs.resize(d->n.encoded_size(Botan::BigInt::Decimal)); - Botan::BigInt::encode((Botan::byte *)cs.data(), d->n, Botan::BigInt::Decimal); - } - catch(std::exception &) - { - return QString(); - } + QByteArray cs; + try { + cs.resize(d->n.encoded_size(Botan::BigInt::Decimal)); + Botan::BigInt::encode((Botan::byte *)cs.data(), d->n, Botan::BigInt::Decimal); + } catch (std::exception &) { + return QString(); + } - QString str; - if(d->n.is_negative()) - str += '-'; - str += QString::fromLatin1(cs); - return str; + QString str; + if (d->n.is_negative()) { + str += '-'; + } + str += QString::fromLatin1(cs); + return str; } bool BigInteger::fromString(const QString &s) { - if(s.isEmpty()) - return false; - QByteArray cs = s.toLatin1(); - - bool neg = false; - if(s[0] == '-') - neg = true; - - try - { - d->n = Botan::BigInt::decode((const Botan::byte *)cs.data() + (neg ? 1 : 0), cs.length() - (neg ? 1 : 0), Botan::BigInt::Decimal); - } - catch(std::exception &) - { - return false; - } - - if(neg) - d->n.set_sign(Botan::BigInt::Negative); - else - d->n.set_sign(Botan::BigInt::Positive); - return true; + if (s.isEmpty()) { + return false; + } + QByteArray cs = s.toLatin1(); + + bool neg = false; + if (s[0] == '-') { + neg = true; + } + + try { + d->n = Botan::BigInt::decode((const Botan::byte *)cs.data() + (neg ? 1 : 0), cs.length() - (neg ? 1 : 0), Botan::BigInt::Decimal); + } catch (std::exception &) { + return false; + } + + if (neg) { + d->n.set_sign(Botan::BigInt::Negative); + } else { + d->n.set_sign(Botan::BigInt::Positive); + } + return true; } } diff --git a/src/support/console.cpp b/src/support/console.cpp --- a/src/support/console.cpp +++ b/src/support/console.cpp @@ -46,980 +46,969 @@ Q_DECLARE_METATYPE(QCA::SecureArray) -namespace QCA { +namespace QCA +{ //---------------------------------------------------------------------------- // ConsoleWorker //---------------------------------------------------------------------------- class ConsoleWorker : public QObject { - Q_OBJECT + Q_OBJECT private: - QPipeEnd in, out; - bool started; - QByteArray in_left, out_left; + QPipeEnd in, out; + bool started; + QByteArray in_left, out_left; public: - ConsoleWorker(QObject *parent = 0) : QObject(parent), in(this), out(this) - { - started = false; - } - - ~ConsoleWorker() - { - stop(); - } - - void start(Q_PIPE_ID in_id, Q_PIPE_ID out_id) - { - Q_ASSERT(!started); - - if(in_id != INVALID_Q_PIPE_ID) - { - in.take(in_id, QPipeDevice::Read); - connect(&in, SIGNAL(readyRead()), SLOT(in_readyRead())); - connect(&in, SIGNAL(closed()), SLOT(in_closed())); - connect(&in, SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(in_error(QCA::QPipeEnd::Error))); - in.enable(); - } - - if(out_id != INVALID_Q_PIPE_ID) - { - out.take(out_id, QPipeDevice::Write); - connect(&out, SIGNAL(bytesWritten(int)), SLOT(out_bytesWritten(int))); - connect(&out, SIGNAL(closed()), SLOT(out_closed())); - out.enable(); - } - - started = true; - } - - void stop() - { - if(!started) - return; - - if(in.isValid()) - in.finalizeAndRelease(); - if(out.isValid()) - out.release(); - - in_left = in.read(); - out_left = out.takeBytesToWrite(); - - started = false; - } + ConsoleWorker(QObject *parent = 0) : QObject(parent), in(this), out(this) + { + started = false; + } + + ~ConsoleWorker() + { + stop(); + } + + void start(Q_PIPE_ID in_id, Q_PIPE_ID out_id) + { + Q_ASSERT(!started); + + if (in_id != INVALID_Q_PIPE_ID) { + in.take(in_id, QPipeDevice::Read); + connect(&in, SIGNAL(readyRead()), SLOT(in_readyRead())); + connect(&in, SIGNAL(closed()), SLOT(in_closed())); + connect(&in, SIGNAL(error(QCA::QPipeEnd::Error)), SLOT(in_error(QCA::QPipeEnd::Error))); + in.enable(); + } + + if (out_id != INVALID_Q_PIPE_ID) { + out.take(out_id, QPipeDevice::Write); + connect(&out, SIGNAL(bytesWritten(int)), SLOT(out_bytesWritten(int))); + connect(&out, SIGNAL(closed()), SLOT(out_closed())); + out.enable(); + } + + started = true; + } + + void stop() + { + if (!started) { + return; + } + + if (in.isValid()) { + in.finalizeAndRelease(); + } + if (out.isValid()) { + out.release(); + } + + in_left = in.read(); + out_left = out.takeBytesToWrite(); + + started = false; + } public slots: - bool isValid() const - { - return in.isValid(); - } - - void setSecurityEnabled(bool enabled) - { - if(in.isValid()) - in.setSecurityEnabled(enabled); - if(out.isValid()) - out.setSecurityEnabled(enabled); - } - - QByteArray read(int bytes = -1) - { - return in.read(bytes); - } - - void write(const QByteArray &a) - { - out.write(a); - } - - QCA::SecureArray readSecure(int bytes = -1) - { - return in.readSecure(bytes); - } - - void writeSecure(const QCA::SecureArray &a) - { - out.writeSecure(a); - } - - void closeOutput() - { - out.close(); - } - - int bytesAvailable() const - { - return in.bytesAvailable(); - } - - int bytesToWrite() const - { - return in.bytesToWrite(); - } + bool isValid() const + { + return in.isValid(); + } + + void setSecurityEnabled(bool enabled) + { + if (in.isValid()) { + in.setSecurityEnabled(enabled); + } + if (out.isValid()) { + out.setSecurityEnabled(enabled); + } + } + + QByteArray read(int bytes = -1) + { + return in.read(bytes); + } + + void write(const QByteArray &a) + { + out.write(a); + } + + QCA::SecureArray readSecure(int bytes = -1) + { + return in.readSecure(bytes); + } + + void writeSecure(const QCA::SecureArray &a) + { + out.writeSecure(a); + } + + void closeOutput() + { + out.close(); + } + + int bytesAvailable() const + { + return in.bytesAvailable(); + } + + int bytesToWrite() const + { + return in.bytesToWrite(); + } public: - QByteArray takeBytesToRead() - { - QByteArray a = in_left; - in_left.clear(); - return a; - } - - QByteArray takeBytesToWrite() - { - QByteArray a = out_left; - out_left.clear(); - return a; - } + QByteArray takeBytesToRead() + { + QByteArray a = in_left; + in_left.clear(); + return a; + } + + QByteArray takeBytesToWrite() + { + QByteArray a = out_left; + out_left.clear(); + return a; + } signals: - void readyRead(); - void bytesWritten(int bytes); - void inputClosed(); - void outputClosed(); + void readyRead(); + void bytesWritten(int bytes); + void inputClosed(); + void outputClosed(); private slots: - void in_readyRead() - { - emit readyRead(); - } - - void out_bytesWritten(int bytes) - { - emit bytesWritten(bytes); - } - - void in_closed() - { - emit inputClosed(); - } - - void in_error(QCA::QPipeEnd::Error) - { - emit inputClosed(); - } - - void out_closed() - { - emit outputClosed(); - } + void in_readyRead() + { + emit readyRead(); + } + + void out_bytesWritten(int bytes) + { + emit bytesWritten(bytes); + } + + void in_closed() + { + emit inputClosed(); + } + + void in_error(QCA::QPipeEnd::Error) + { + emit inputClosed(); + } + + void out_closed() + { + emit outputClosed(); + } }; //---------------------------------------------------------------------------- // ConsoleThread //---------------------------------------------------------------------------- class ConsoleThread : public SyncThread { - Q_OBJECT + Q_OBJECT public: - ConsoleWorker *worker; - Q_PIPE_ID _in_id, _out_id; - QByteArray in_left, out_left; - QMutex call_mutex; - - ConsoleThread(QObject *parent = 0) : SyncThread(parent) - { - qRegisterMetaType("QCA::SecureArray"); - } - - ~ConsoleThread() - { - stop(); - } - - void start(Q_PIPE_ID in_id, Q_PIPE_ID out_id) - { - _in_id = in_id; - _out_id = out_id; - SyncThread::start(); - } - - void stop() - { - SyncThread::stop(); - } - - QVariant mycall(QObject *obj, const char *method, const QVariantList &args = QVariantList()) - { - QVariant ret; - bool ok; - - call_mutex.lock(); - ret = call(obj, method, args, &ok); - call_mutex.unlock(); - - Q_ASSERT(ok); - if(!ok) - { - fprintf(stderr, "QCA: ConsoleWorker call [%s] failed.\n", method); - abort(); - return QVariant(); - } - return ret; - } - - bool isValid() - { - return mycall(worker, "isValid").toBool(); - } - - void setSecurityEnabled(bool enabled) - { - mycall(worker, "setSecurityEnabled", QVariantList() << enabled); - } - - QByteArray read(int bytes = -1) - { - return mycall(worker, "read", QVariantList() << bytes).toByteArray(); - } - - void write(const QByteArray &a) - { - mycall(worker, "write", QVariantList() << a); - } - - SecureArray readSecure(int bytes = -1) - { + ConsoleWorker *worker; + Q_PIPE_ID _in_id, _out_id; + QByteArray in_left, out_left; + QMutex call_mutex; + + ConsoleThread(QObject *parent = 0) : SyncThread(parent) + { + qRegisterMetaType("QCA::SecureArray"); + } + + ~ConsoleThread() + { + stop(); + } + + void start(Q_PIPE_ID in_id, Q_PIPE_ID out_id) + { + _in_id = in_id; + _out_id = out_id; + SyncThread::start(); + } + + void stop() + { + SyncThread::stop(); + } + + QVariant mycall(QObject *obj, const char *method, const QVariantList &args = QVariantList()) + { + QVariant ret; + bool ok; + + call_mutex.lock(); + ret = call(obj, method, args, &ok); + call_mutex.unlock(); + + Q_ASSERT(ok); + if (!ok) { + fprintf(stderr, "QCA: ConsoleWorker call [%s] failed.\n", method); + abort(); + return QVariant(); + } + return ret; + } + + bool isValid() + { + return mycall(worker, "isValid").toBool(); + } + + void setSecurityEnabled(bool enabled) + { + mycall(worker, "setSecurityEnabled", QVariantList() << enabled); + } + + QByteArray read(int bytes = -1) + { + return mycall(worker, "read", QVariantList() << bytes).toByteArray(); + } + + void write(const QByteArray &a) + { + mycall(worker, "write", QVariantList() << a); + } + + SecureArray readSecure(int bytes = -1) + { #if QT_VERSION >= 0x050000 - return mycall(worker, "readSecure", QVariantList() << bytes).value(); + return mycall(worker, "readSecure", QVariantList() << bytes).value(); #else - return qVariantValue(mycall(worker, "readSecure", QVariantList() << bytes)); + return qVariantValue(mycall(worker, "readSecure", QVariantList() << bytes)); #endif - } - - void writeSecure(const SecureArray &a) - { - mycall(worker, "writeSecure", QVariantList() << qVariantFromValue(a)); - } - - void closeOutput() - { - mycall(worker, "closeOutput"); - } - - int bytesAvailable() - { - return mycall(worker, "bytesAvailable").toInt(); - } - - int bytesToWrite() - { - return mycall(worker, "bytesToWrite").toInt(); - } - - QByteArray takeBytesToRead() - { - QByteArray a = in_left; - in_left.clear(); - return a; - } - - QByteArray takeBytesToWrite() - { - QByteArray a = out_left; - out_left.clear(); - return a; - } + } + + void writeSecure(const SecureArray &a) + { + mycall(worker, "writeSecure", QVariantList() << qVariantFromValue(a)); + } + + void closeOutput() + { + mycall(worker, "closeOutput"); + } + + int bytesAvailable() + { + return mycall(worker, "bytesAvailable").toInt(); + } + + int bytesToWrite() + { + return mycall(worker, "bytesToWrite").toInt(); + } + + QByteArray takeBytesToRead() + { + QByteArray a = in_left; + in_left.clear(); + return a; + } + + QByteArray takeBytesToWrite() + { + QByteArray a = out_left; + out_left.clear(); + return a; + } signals: - void readyRead(); - void bytesWritten(int); - void inputClosed(); - void outputClosed(); + void readyRead(); + void bytesWritten(int); + void inputClosed(); + void outputClosed(); protected: - virtual void atStart() - { - worker = new ConsoleWorker; - - // use direct connections here, so that the emits come from - // the other thread. we can also connect to our own - // signals to avoid having to make slots just to emit. - connect(worker, SIGNAL(readyRead()), SIGNAL(readyRead()), Qt::DirectConnection); - connect(worker, SIGNAL(bytesWritten(int)), SIGNAL(bytesWritten(int)), Qt::DirectConnection); - connect(worker, SIGNAL(inputClosed()), SIGNAL(inputClosed()), Qt::DirectConnection); - connect(worker, SIGNAL(outputClosed()), SIGNAL(outputClosed()), Qt::DirectConnection); - - worker->start(_in_id, _out_id); - } - - virtual void atEnd() - { - in_left = worker->takeBytesToRead(); - out_left = worker->takeBytesToWrite(); - delete worker; - } + virtual void atStart() + { + worker = new ConsoleWorker; + + // use direct connections here, so that the emits come from + // the other thread. we can also connect to our own + // signals to avoid having to make slots just to emit. + connect(worker, SIGNAL(readyRead()), SIGNAL(readyRead()), Qt::DirectConnection); + connect(worker, SIGNAL(bytesWritten(int)), SIGNAL(bytesWritten(int)), Qt::DirectConnection); + connect(worker, SIGNAL(inputClosed()), SIGNAL(inputClosed()), Qt::DirectConnection); + connect(worker, SIGNAL(outputClosed()), SIGNAL(outputClosed()), Qt::DirectConnection); + + worker->start(_in_id, _out_id); + } + + virtual void atEnd() + { + in_left = worker->takeBytesToRead(); + out_left = worker->takeBytesToWrite(); + delete worker; + } }; //---------------------------------------------------------------------------- // Console //---------------------------------------------------------------------------- class ConsolePrivate : public QObject { - Q_OBJECT + Q_OBJECT public: - Console *q; + Console *q; - bool started; - Console::Type type; - Console::ChannelMode cmode; - Console::TerminalMode mode; - ConsoleThread *thread; - ConsoleReference *ref; - Q_PIPE_ID in_id; + bool started; + Console::Type type; + Console::ChannelMode cmode; + Console::TerminalMode mode; + ConsoleThread *thread; + ConsoleReference *ref; + Q_PIPE_ID in_id; #ifdef Q_OS_WIN - DWORD old_mode; + DWORD old_mode; #else - struct termios old_term_attr; + struct termios old_term_attr; #endif - ConsolePrivate(Console *_q) : QObject(_q), q(_q) - { - started = false; - mode = Console::Default; - thread = new ConsoleThread(this); - ref = 0; - } - - ~ConsolePrivate() - { - delete thread; - setInteractive(Console::Default); - } - - void setInteractive(Console::TerminalMode m) - { - // no change - if(m == mode) - return; - - if(m == Console::Interactive) - { + ConsolePrivate(Console *_q) : QObject(_q), q(_q) + { + started = false; + mode = Console::Default; + thread = new ConsoleThread(this); + ref = 0; + } + + ~ConsolePrivate() + { + delete thread; + setInteractive(Console::Default); + } + + void setInteractive(Console::TerminalMode m) + { + // no change + if (m == mode) { + return; + } + + if (m == Console::Interactive) { #ifdef Q_OS_WIN - GetConsoleMode(in_id, &old_mode); - SetConsoleMode(in_id, old_mode & (~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT)); + GetConsoleMode(in_id, &old_mode); + SetConsoleMode(in_id, old_mode & (~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT)); #else - int fd = in_id; - struct termios attr; - tcgetattr(fd, &attr); - old_term_attr = attr; - - attr.c_lflag &= ~(ECHO); // turn off the echo flag - attr.c_lflag &= ~(ICANON); // no wait for a newline - attr.c_cc[VMIN] = 1; // read at least 1 char - attr.c_cc[VTIME] = 0; // set wait time to zero - - // set the new attributes - tcsetattr(fd, TCSAFLUSH, &attr); + int fd = in_id; + struct termios attr; + tcgetattr(fd, &attr); + old_term_attr = attr; + + attr.c_lflag &= ~(ECHO); // turn off the echo flag + attr.c_lflag &= ~(ICANON); // no wait for a newline + attr.c_cc[VMIN] = 1; // read at least 1 char + attr.c_cc[VTIME] = 0; // set wait time to zero + + // set the new attributes + tcsetattr(fd, TCSAFLUSH, &attr); #endif - } - else - { + } else { #ifdef Q_OS_WIN - SetConsoleMode(in_id, old_mode); + SetConsoleMode(in_id, old_mode); #else - int fd = in_id; - tcsetattr(fd, TCSANOW, &old_term_attr); + int fd = in_id; + tcsetattr(fd, TCSANOW, &old_term_attr); #endif - } + } - mode = m; - } + mode = m; + } }; static Console *g_tty_console = 0, *g_stdio_console = 0; Console::Console(Type type, ChannelMode cmode, TerminalMode tmode, QObject *parent) -:QObject(parent) + : QObject(parent) { - if(type == Tty) - { - Q_ASSERT(g_tty_console == 0); - g_tty_console = this; - } - else - { - Q_ASSERT(g_stdio_console == 0); - g_stdio_console = this; - } - - d = new ConsolePrivate(this); - d->type = type; - d->cmode = cmode; - - Q_PIPE_ID in = INVALID_Q_PIPE_ID; - Q_PIPE_ID out = INVALID_Q_PIPE_ID; + if (type == Tty) { + Q_ASSERT(g_tty_console == 0); + g_tty_console = this; + } else { + Q_ASSERT(g_stdio_console == 0); + g_stdio_console = this; + } + + d = new ConsolePrivate(this); + d->type = type; + d->cmode = cmode; + + Q_PIPE_ID in = INVALID_Q_PIPE_ID; + Q_PIPE_ID out = INVALID_Q_PIPE_ID; #ifdef Q_OS_WIN - if(type == Tty) - { - in = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, 0, NULL); - } - else - { - in = GetStdHandle(STD_INPUT_HANDLE); - } + if (type == Tty) { + in = CreateFileA("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); + } else { + in = GetStdHandle(STD_INPUT_HANDLE); + } #else - if(type == Tty) - { - in = open("/dev/tty", O_RDONLY); - } - else - { - in = 0; // stdin - } + if (type == Tty) { + in = open("/dev/tty", O_RDONLY); + } else { + in = 0; // stdin + } #endif - if(cmode == ReadWrite) - { + if (cmode == ReadWrite) { #ifdef Q_OS_WIN - if(type == Tty) - { - out = CreateFileA("CONOUT$", - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, 0, NULL); - } - else - { - out = GetStdHandle(STD_OUTPUT_HANDLE); - } + if (type == Tty) { + out = CreateFileA("CONOUT$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); + } else { + out = GetStdHandle(STD_OUTPUT_HANDLE); + } #else - if(type == Tty) - { - out = open("/dev/tty", O_WRONLY); - } - else - { - out = 1; // stdout - } + if (type == Tty) { + out = open("/dev/tty", O_WRONLY); + } else { + out = 1; // stdout + } #endif - } + } - d->in_id = in; - d->setInteractive(tmode); - d->thread->start(in, out); + d->in_id = in; + d->setInteractive(tmode); + d->thread->start(in, out); } Console::~Console() { - release(); - Console::Type type = d->type; - delete d; - if(type == Tty) - g_tty_console = 0; - else - g_stdio_console = 0; + release(); + Console::Type type = d->type; + delete d; + if (type == Tty) { + g_tty_console = 0; + } else { + g_stdio_console = 0; + } } Console::Type Console::type() const { - return d->type; + return d->type; } Console::ChannelMode Console::channelMode() const { - return d->cmode; + return d->cmode; } Console::TerminalMode Console::terminalMode() const { - return d->mode; + return d->mode; } bool Console::isStdinRedirected() { #ifdef Q_OS_WIN - HANDLE h = GetStdHandle(STD_INPUT_HANDLE); - DWORD mode; - if(GetConsoleMode(h, &mode)) - return false; - return true; + HANDLE h = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode; + if (GetConsoleMode(h, &mode)) { + return false; + } + return true; #else - return (isatty(0) ? false : true); // 0 == stdin + return (isatty(0) ? false : true); // 0 == stdin #endif } bool Console::isStdoutRedirected() { #ifdef Q_OS_WIN - HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD mode; - if(GetConsoleMode(h, &mode)) - return false; - return true; + HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD mode; + if (GetConsoleMode(h, &mode)) { + return false; + } + return true; #else - return (isatty(1) ? false : true); // 1 == stdout + return (isatty(1) ? false : true); // 1 == stdout #endif } Console *Console::ttyInstance() { - return g_tty_console; + return g_tty_console; } Console *Console::stdioInstance() { - return g_stdio_console; + return g_stdio_console; } void Console::release() { - d->thread->stop(); + d->thread->stop(); } QByteArray Console::bytesLeftToRead() { - return d->thread->takeBytesToRead(); + return d->thread->takeBytesToRead(); } QByteArray Console::bytesLeftToWrite() { - return d->thread->takeBytesToWrite(); + return d->thread->takeBytesToWrite(); } //---------------------------------------------------------------------------- // ConsoleReference //---------------------------------------------------------------------------- class ConsoleReferencePrivate : public QObject { - Q_OBJECT + Q_OBJECT public: - ConsoleReference *q; - - Console *console; - ConsoleThread *thread; - ConsoleReference::SecurityMode smode; - SafeTimer lateTrigger; - bool late_read, late_close; - - ConsoleReferencePrivate(ConsoleReference *_q) : QObject(_q), q(_q), lateTrigger(this) - { - console = 0; - thread = 0; - connect(&lateTrigger, SIGNAL(timeout()), SLOT(doLate())); - lateTrigger.setSingleShot(true); - } + ConsoleReference *q; + + Console *console; + ConsoleThread *thread; + ConsoleReference::SecurityMode smode; + SafeTimer lateTrigger; + bool late_read, late_close; + + ConsoleReferencePrivate(ConsoleReference *_q) : QObject(_q), q(_q), lateTrigger(this) + { + console = 0; + thread = 0; + connect(&lateTrigger, SIGNAL(timeout()), SLOT(doLate())); + lateTrigger.setSingleShot(true); + } private slots: - void doLate() - { - QPointer self = this; - if(late_read) - emit q->readyRead(); - if(!self) - return; - if(late_close) - emit q->inputClosed(); - } + void doLate() + { + QPointer self = this; + if (late_read) { + emit q->readyRead(); + } + if (!self) { + return; + } + if (late_close) { + emit q->inputClosed(); + } + } }; ConsoleReference::ConsoleReference(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new ConsoleReferencePrivate(this); + d = new ConsoleReferencePrivate(this); } ConsoleReference::~ConsoleReference() { - stop(); - delete d; + stop(); + delete d; } bool ConsoleReference::start(Console *console, SecurityMode mode) { - // make sure this reference isn't using a console already - Q_ASSERT(!d->console); + // make sure this reference isn't using a console already + Q_ASSERT(!d->console); - // one console reference at a time - Q_ASSERT(console->d->ref == 0); + // one console reference at a time + Q_ASSERT(console->d->ref == 0); - // let's take it - d->console = console; - d->thread = d->console->d->thread; - d->console->d->ref = this; + // let's take it + d->console = console; + d->thread = d->console->d->thread; + d->console->d->ref = this; - bool valid = d->thread->isValid(); - int avail = d->thread->bytesAvailable(); + bool valid = d->thread->isValid(); + int avail = d->thread->bytesAvailable(); - // pipe already closed and no data? consider this an error - if(!valid && avail == 0) - { - d->console->d->ref = 0; - d->thread = 0; - d->console = 0; - return false; - } + // pipe already closed and no data? consider this an error + if (!valid && avail == 0) { + d->console->d->ref = 0; + d->thread = 0; + d->console = 0; + return false; + } - // enable security? it will last for this active session only - d->smode = mode; - if(mode == SecurityEnabled) - d->thread->setSecurityEnabled(true); + // enable security? it will last for this active session only + d->smode = mode; + if (mode == SecurityEnabled) { + d->thread->setSecurityEnabled(true); + } - connect(d->thread, SIGNAL(readyRead()), SIGNAL(readyRead())); - connect(d->thread, SIGNAL(bytesWritten(int)), SIGNAL(bytesWritten(int))); - connect(d->thread, SIGNAL(inputClosed()), SIGNAL(inputClosed())); - connect(d->thread, SIGNAL(outputClosed()), SIGNAL(outputClosed())); + connect(d->thread, SIGNAL(readyRead()), SIGNAL(readyRead())); + connect(d->thread, SIGNAL(bytesWritten(int)), SIGNAL(bytesWritten(int))); + connect(d->thread, SIGNAL(inputClosed()), SIGNAL(inputClosed())); + connect(d->thread, SIGNAL(outputClosed()), SIGNAL(outputClosed())); - d->late_read = false; - d->late_close = false; + d->late_read = false; + d->late_close = false; - if(avail > 0) - d->late_read = true; + if (avail > 0) { + d->late_read = true; + } - if(!valid) - d->late_close = true; + if (!valid) { + d->late_close = true; + } - if(d->late_read || d->late_close) - d->lateTrigger.start(); + if (d->late_read || d->late_close) { + d->lateTrigger.start(); + } - return true; + return true; } void ConsoleReference::stop() { - if(!d->console) - return; + if (!d->console) { + return; + } - d->lateTrigger.stop(); + d->lateTrigger.stop(); - disconnect(d->thread, 0, this, 0); + disconnect(d->thread, 0, this, 0); - // automatically disable security when we go inactive - d->thread->setSecurityEnabled(false); + // automatically disable security when we go inactive + d->thread->setSecurityEnabled(false); - d->console->d->ref = 0; - d->thread = 0; - d->console = 0; + d->console->d->ref = 0; + d->thread = 0; + d->console = 0; } Console *ConsoleReference::console() const { - return d->console; + return d->console; } ConsoleReference::SecurityMode ConsoleReference::securityMode() const { - return d->smode; + return d->smode; } QByteArray ConsoleReference::read(int bytes) { - return d->thread->read(bytes); + return d->thread->read(bytes); } void ConsoleReference::write(const QByteArray &a) { - d->thread->write(a); + d->thread->write(a); } SecureArray ConsoleReference::readSecure(int bytes) { - return d->thread->readSecure(bytes); + return d->thread->readSecure(bytes); } void ConsoleReference::writeSecure(const SecureArray &a) { - d->thread->writeSecure(a); + d->thread->writeSecure(a); } void ConsoleReference::closeOutput() { - d->thread->closeOutput(); + d->thread->closeOutput(); } int ConsoleReference::bytesAvailable() const { - return d->thread->bytesAvailable(); + return d->thread->bytesAvailable(); } int ConsoleReference::bytesToWrite() const { - return d->thread->bytesToWrite(); + return d->thread->bytesToWrite(); } //---------------------------------------------------------------------------- // ConsolePrompt //---------------------------------------------------------------------------- class ConsolePrompt::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - ConsolePrompt *q; - - Synchronizer sync; - Console *con; - bool own_con; - ConsoleReference console; - QString promptStr; - SecureArray result; - bool waiting; - int at; - bool done; - bool charMode; - QTextCodec *codec; - QTextCodec::ConverterState *encstate, *decstate; - - Private(ConsolePrompt *_q) : QObject(_q), q(_q), sync(_q), console(this) - { - connect(&console, SIGNAL(readyRead()), SLOT(con_readyRead())); - connect(&console, SIGNAL(inputClosed()), SLOT(con_inputClosed())); - - con = 0; - own_con = false; - waiting = false; + ConsolePrompt *q; + + Synchronizer sync; + Console *con; + bool own_con; + ConsoleReference console; + QString promptStr; + SecureArray result; + bool waiting; + int at; + bool done; + bool charMode; + QTextCodec *codec; + QTextCodec::ConverterState *encstate, *decstate; + + Private(ConsolePrompt *_q) : QObject(_q), q(_q), sync(_q), console(this) + { + connect(&console, SIGNAL(readyRead()), SLOT(con_readyRead())); + connect(&console, SIGNAL(inputClosed()), SLOT(con_inputClosed())); + + con = 0; + own_con = false; + waiting = false; #ifdef Q_OS_WIN - codec = QTextCodec::codecForMib(106); // UTF-8 + codec = QTextCodec::codecForMib(106); // UTF-8 #else - codec = QTextCodec::codecForLocale(); + codec = QTextCodec::codecForLocale(); #endif - encstate = 0; - decstate = 0; - } - - ~Private() - { - reset(); - } - - void reset() - { - delete encstate; - encstate = 0; - delete decstate; - decstate = 0; - - console.stop(); - if(own_con) - { - delete con; - con = 0; - own_con = false; - } - } - - bool start(bool _charMode) - { - own_con = false; - con = Console::ttyInstance(); - if(!con) - { - con = new Console(Console::Tty, Console::ReadWrite, Console::Interactive); - own_con = true; - } - - result.clear(); - at = 0; - done = false; - charMode = _charMode; - - encstate = new QTextCodec::ConverterState(QTextCodec::IgnoreHeader); - decstate = new QTextCodec::ConverterState(QTextCodec::IgnoreHeader); - - if(!console.start(con, ConsoleReference::SecurityEnabled)) - { - reset(); - fprintf(stderr, "Console input not available or closed\n"); - return false; - } - - if(!charMode) - writeString(promptStr + ": "); - - return true; - } - - void writeString(const QString &str) - { - console.writeSecure(codec->fromUnicode(str.unicode(), str.length(), encstate)); - } - - // process each char. internally store the result as utf16, which - // is easier to edit (e.g. backspace) - bool processChar(QChar c) - { - if(charMode) - { - appendChar(c); - done = true; - return false; - } - - if(c == '\r' || c == '\n') - { - writeString("\n"); - done = true; - return false; - } - - if(c == '\b' || c.unicode() == 0x7f) - { - if(at > 0) - { - --at; - writeString("\b \b"); - result.resize(at * sizeof(ushort)); - } - return true; - } - else if(c < 0x20) - return true; - - if(at >= CONSOLEPROMPT_INPUT_MAX) - return true; - - appendChar(c); - - writeString("*"); - return true; - } - - void appendChar(QChar c) - { - if((at + 1) * (int)sizeof(ushort) > result.size()) - result.resize((at + 1) * sizeof(ushort)); - ushort *p = (ushort *)result.data(); - p[at++] = c.unicode(); - } - - void convertToUtf8() - { - // convert result from utf16 to utf8, securely - QTextCodec *codec = QTextCodec::codecForMib(106); - QTextCodec::ConverterState cstate(QTextCodec::IgnoreHeader); - SecureArray out; - ushort *ustr = (ushort *)result.data(); - int len = result.size() / sizeof(ushort); - for(int n = 0; n < len; ++n) - { - QChar c(ustr[n]); - out += codec->fromUnicode(&c, 1, &cstate); - } - result = out; - } + encstate = 0; + decstate = 0; + } + + ~Private() + { + reset(); + } + + void reset() + { + delete encstate; + encstate = 0; + delete decstate; + decstate = 0; + + console.stop(); + if (own_con) { + delete con; + con = 0; + own_con = false; + } + } + + bool start(bool _charMode) + { + own_con = false; + con = Console::ttyInstance(); + if (!con) { + con = new Console(Console::Tty, Console::ReadWrite, Console::Interactive); + own_con = true; + } + + result.clear(); + at = 0; + done = false; + charMode = _charMode; + + encstate = new QTextCodec::ConverterState(QTextCodec::IgnoreHeader); + decstate = new QTextCodec::ConverterState(QTextCodec::IgnoreHeader); + + if (!console.start(con, ConsoleReference::SecurityEnabled)) { + reset(); + fprintf(stderr, "Console input not available or closed\n"); + return false; + } + + if (!charMode) { + writeString(promptStr + ": "); + } + + return true; + } + + void writeString(const QString &str) + { + console.writeSecure(codec->fromUnicode(str.unicode(), str.length(), encstate)); + } + + // process each char. internally store the result as utf16, which + // is easier to edit (e.g. backspace) + bool processChar(QChar c) + { + if (charMode) { + appendChar(c); + done = true; + return false; + } + + if (c == '\r' || c == '\n') { + writeString("\n"); + done = true; + return false; + } + + if (c == '\b' || c.unicode() == 0x7f) { + if (at > 0) { + --at; + writeString("\b \b"); + result.resize(at * sizeof(ushort)); + } + return true; + } else if (c < 0x20) { + return true; + } + + if (at >= CONSOLEPROMPT_INPUT_MAX) { + return true; + } + + appendChar(c); + + writeString("*"); + return true; + } + + void appendChar(QChar c) + { + if ((at + 1) * (int)sizeof(ushort) > result.size()) { + result.resize((at + 1) * sizeof(ushort)); + } + ushort *p = (ushort *)result.data(); + p[at++] = c.unicode(); + } + + void convertToUtf8() + { + // convert result from utf16 to utf8, securely + QTextCodec *codec = QTextCodec::codecForMib(106); + QTextCodec::ConverterState cstate(QTextCodec::IgnoreHeader); + SecureArray out; + ushort *ustr = (ushort *)result.data(); + int len = result.size() / sizeof(ushort); + for (int n = 0; n < len; ++n) { + QChar c(ustr[n]); + out += codec->fromUnicode(&c, 1, &cstate); + } + result = out; + } private slots: - void con_readyRead() - { - while(console.bytesAvailable() > 0) - { - SecureArray buf = console.readSecure(1); - if(buf.isEmpty()) - break; - - // convert to unicode and process - QString str = codec->toUnicode(buf.data(), 1, decstate); - bool quit = false; - for(int n = 0; n < str.length(); ++n) - { - if(!processChar(str[n])) - { - quit = true; - break; - } - } - if(quit) - break; - } - - if(done) - { - convertToUtf8(); - - reset(); - if(waiting) - sync.conditionMet(); - else - emit q->finished(); - } - } - - void con_inputClosed() - { - fprintf(stderr, "Console input closed\n"); - if(!done) - { - done = true; - result.clear(); - - reset(); - if(waiting) - sync.conditionMet(); - else - emit q->finished(); - } - } + void con_readyRead() + { + while (console.bytesAvailable() > 0) { + SecureArray buf = console.readSecure(1); + if (buf.isEmpty()) { + break; + } + + // convert to unicode and process + QString str = codec->toUnicode(buf.data(), 1, decstate); + bool quit = false; + for (int n = 0; n < str.length(); ++n) { + if (!processChar(str[n])) { + quit = true; + break; + } + } + if (quit) { + break; + } + } + + if (done) { + convertToUtf8(); + + reset(); + if (waiting) { + sync.conditionMet(); + } else { + emit q->finished(); + } + } + } + + void con_inputClosed() + { + fprintf(stderr, "Console input closed\n"); + if (!done) { + done = true; + result.clear(); + + reset(); + if (waiting) { + sync.conditionMet(); + } else { + emit q->finished(); + } + } + } }; ConsolePrompt::ConsolePrompt(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); + d = new Private(this); } ConsolePrompt::~ConsolePrompt() { - delete d; + delete d; } void ConsolePrompt::getHidden(const QString &promptStr) { - d->reset(); - - d->promptStr = promptStr; - if(!d->start(false)) - { - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - return; - } + d->reset(); + + d->promptStr = promptStr; + if (!d->start(false)) { + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + return; + } } void ConsolePrompt::getChar() { - d->reset(); + d->reset(); - if(!d->start(true)) - { - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - return; - } + if (!d->start(true)) { + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); + return; + } } void ConsolePrompt::waitForFinished() { - // reparent the Console under us (for Synchronizer) - QObject *orig_parent = d->con->parent(); - d->con->setParent(this); - - // block while prompting - d->waiting = true; - d->sync.waitForCondition(); - d->waiting = false; - - // restore parent (if con still exists) - if(d->con) - d->con->setParent(orig_parent); + // reparent the Console under us (for Synchronizer) + QObject *orig_parent = d->con->parent(); + d->con->setParent(this); + + // block while prompting + d->waiting = true; + d->sync.waitForCondition(); + d->waiting = false; + + // restore parent (if con still exists) + if (d->con) { + d->con->setParent(orig_parent); + } } SecureArray ConsolePrompt::result() const { - return d->result; + return d->result; } QChar ConsolePrompt::resultChar() const { - QString str = QString::fromUtf8(d->result.toByteArray()); + QString str = QString::fromUtf8(d->result.toByteArray()); - // this will never happen if getChar completes - if(str.isEmpty()) - return QChar(); + // this will never happen if getChar completes + if (str.isEmpty()) { + return QChar(); + } - return str[0]; + return str[0]; } } diff --git a/src/support/dirwatch.cpp b/src/support/dirwatch.cpp --- a/src/support/dirwatch.cpp +++ b/src/support/dirwatch.cpp @@ -27,227 +27,224 @@ #include #include "qca_safeobj.h" -namespace QCA { +namespace QCA +{ // this gets us DOR-SS and SR, provided we delete the object between uses. // we assume QFileSystemWatcher complies to DS,NE. class QFileSystemWatcherRelay : public QObject { - Q_OBJECT + Q_OBJECT public: - QFileSystemWatcher *watcher; + QFileSystemWatcher *watcher; - QFileSystemWatcherRelay(QFileSystemWatcher *_watcher, QObject *parent = 0) - :QObject(parent), watcher(_watcher) - { - connect(watcher, SIGNAL(directoryChanged(const QString &)), SIGNAL(directoryChanged(const QString &)), Qt::QueuedConnection); - connect(watcher, SIGNAL(fileChanged(const QString &)), SIGNAL(fileChanged(const QString &)), Qt::QueuedConnection); - } + QFileSystemWatcherRelay(QFileSystemWatcher *_watcher, QObject *parent = 0) + : QObject(parent), watcher(_watcher) + { + connect(watcher, SIGNAL(directoryChanged(QString)), SIGNAL(directoryChanged(QString)), Qt::QueuedConnection); + connect(watcher, SIGNAL(fileChanged(QString)), SIGNAL(fileChanged(QString)), Qt::QueuedConnection); + } signals: - void directoryChanged(const QString &path); - void fileChanged(const QString &path); + void directoryChanged(const QString &path); + void fileChanged(const QString &path); }; //---------------------------------------------------------------------------- // DirWatch //---------------------------------------------------------------------------- class DirWatch::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - DirWatch *q; - QFileSystemWatcher *watcher; - QFileSystemWatcherRelay *watcher_relay; - QString dirName; + DirWatch *q; + QFileSystemWatcher *watcher; + QFileSystemWatcherRelay *watcher_relay; + QString dirName; - Private(DirWatch *_q) : QObject(_q), q(_q), watcher(0), watcher_relay(0) - { - } + Private(DirWatch *_q) : QObject(_q), q(_q), watcher(0), watcher_relay(0) + { + } private slots: - void watcher_changed(const QString &path) - { - Q_UNUSED(path); - emit q->changed(); - } + void watcher_changed(const QString &path) + { + Q_UNUSED(path); + emit q->changed(); + } }; DirWatch::DirWatch(const QString &dir, QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); - setDirName(dir); + d = new Private(this); + setDirName(dir); } DirWatch::~DirWatch() { - delete d; + delete d; } QString DirWatch::dirName() const { - return d->dirName; + return d->dirName; } void DirWatch::setDirName(const QString &dir) { - if(d->watcher) - { - delete d->watcher; - delete d->watcher_relay; - d->watcher = 0; - d->watcher_relay = 0; - } - - d->dirName = dir; - - if(!d->dirName.isEmpty() && QFileInfo(d->dirName).isDir()) - { - d->watcher = new QFileSystemWatcher(this); - d->watcher_relay = new QFileSystemWatcherRelay(d->watcher, this); - connect(d->watcher_relay, SIGNAL(directoryChanged(const QString &)), d, SLOT(watcher_changed(const QString &))); - - d->watcher->addPath(d->dirName); - } + if (d->watcher) { + delete d->watcher; + delete d->watcher_relay; + d->watcher = 0; + d->watcher_relay = 0; + } + + d->dirName = dir; + + if (!d->dirName.isEmpty() && QFileInfo(d->dirName).isDir()) { + d->watcher = new QFileSystemWatcher(this); + d->watcher_relay = new QFileSystemWatcherRelay(d->watcher, this); + connect(d->watcher_relay, SIGNAL(directoryChanged(QString)), d, SLOT(watcher_changed(QString))); + + d->watcher->addPath(d->dirName); + } } //---------------------------------------------------------------------------- // FileWatch //---------------------------------------------------------------------------- class FileWatch::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - FileWatch *q; - QFileSystemWatcher *watcher; - QFileSystemWatcherRelay *watcher_relay; - QString fileName; // file (optionally w/ path) as provided by user - QString filePath; // absolute path of file, calculated by us - bool fileExisted; - - Private(FileWatch *_q) : QObject(_q), q(_q), watcher(0), watcher_relay(0) - { - } - - void start(const QString &_fileName) - { - fileName = _fileName; - - watcher = new QFileSystemWatcher(this); - watcher_relay = new QFileSystemWatcherRelay(watcher, this); - connect(watcher_relay, SIGNAL(directoryChanged(const QString &)), SLOT(dir_changed(const QString &))); - connect(watcher_relay, SIGNAL(fileChanged(const QString &)), SLOT(file_changed(const QString &))); - - QFileInfo fi(fileName); - fi.makeAbsolute(); - filePath = fi.filePath(); - QDir dir = fi.dir(); - - // we watch both the directory and the file itself. the - // reason we watch the directory is so we can detect when - // the file is deleted/created - - // we don't bother checking for dir existence before adding, - // since there isn't an atomic way to do both at once. if - // it turns out that the dir doesn't exist, then the - // monitoring will just silently not work at all. - - watcher->addPath(dir.path()); - - // can't watch for non-existent directory - if(!watcher->directories().contains(dir.path())) - { - stop(); - return; - } - - // save whether or not the file exists - fileExisted = fi.exists(); - - // add only if file existent - // if no it will be added on directoryChanged signal - if(fileExisted) - watcher->addPath(filePath); - - // TODO: address race conditions and think about error - // reporting instead of silently failing. probably this - // will require a Qt API update. - } - - void stop() - { - if(watcher) - { - delete watcher; - delete watcher_relay; - watcher = 0; - watcher_relay = 0; - } - - fileName.clear(); - filePath.clear(); - } + FileWatch *q; + QFileSystemWatcher *watcher; + QFileSystemWatcherRelay *watcher_relay; + QString fileName; // file (optionally w/ path) as provided by user + QString filePath; // absolute path of file, calculated by us + bool fileExisted; + + Private(FileWatch *_q) : QObject(_q), q(_q), watcher(0), watcher_relay(0) + { + } + + void start(const QString &_fileName) + { + fileName = _fileName; + + watcher = new QFileSystemWatcher(this); + watcher_relay = new QFileSystemWatcherRelay(watcher, this); + connect(watcher_relay, SIGNAL(directoryChanged(QString)), SLOT(dir_changed(QString))); + connect(watcher_relay, SIGNAL(fileChanged(QString)), SLOT(file_changed(QString))); + + QFileInfo fi(fileName); + fi.makeAbsolute(); + filePath = fi.filePath(); + QDir dir = fi.dir(); + + // we watch both the directory and the file itself. the + // reason we watch the directory is so we can detect when + // the file is deleted/created + + // we don't bother checking for dir existence before adding, + // since there isn't an atomic way to do both at once. if + // it turns out that the dir doesn't exist, then the + // monitoring will just silently not work at all. + + watcher->addPath(dir.path()); + + // can't watch for non-existent directory + if (!watcher->directories().contains(dir.path())) { + stop(); + return; + } + + // save whether or not the file exists + fileExisted = fi.exists(); + + // add only if file existent + // if no it will be added on directoryChanged signal + if (fileExisted) { + watcher->addPath(filePath); + } + + // TODO: address race conditions and think about error + // reporting instead of silently failing. probably this + // will require a Qt API update. + } + + void stop() + { + if (watcher) { + delete watcher; + delete watcher_relay; + watcher = 0; + watcher_relay = 0; + } + + fileName.clear(); + filePath.clear(); + } private slots: - void dir_changed(const QString &path) - { - Q_UNUSED(path); - QFileInfo fi(filePath); - bool exists = fi.exists(); - if(exists && !fileExisted) - { - // this means the file was created. put a - // watch on it. - fileExisted = true; - watcher->addPath(filePath); - emit q->changed(); - } - } - - void file_changed(const QString &path) - { - Q_UNUSED(path); - QFileInfo fi(filePath); - if (!fi.exists() && !fileExisted) { - // Got a file changed signal on a file that does not exist - // and is not actively watched. This happens when we - // previously watched a file but it was deleted and after - // the original deletion changed-signal we get another one - // (for example because of bad signal timing). In this scenario - // we must ignore the change as the change, whatever it may - // have been, is of no interest to us because we don't watch - // the file and furthermore the file does not even exist. - return; - } else if (!fi.exists()) { - fileExisted = false; - }; - emit q->changed(); - } + void dir_changed(const QString &path) + { + Q_UNUSED(path); + QFileInfo fi(filePath); + bool exists = fi.exists(); + if (exists && !fileExisted) { + // this means the file was created. put a + // watch on it. + fileExisted = true; + watcher->addPath(filePath); + emit q->changed(); + } + } + + void file_changed(const QString &path) + { + Q_UNUSED(path); + QFileInfo fi(filePath); + if (!fi.exists() && !fileExisted) { + // Got a file changed signal on a file that does not exist + // and is not actively watched. This happens when we + // previously watched a file but it was deleted and after + // the original deletion changed-signal we get another one + // (for example because of bad signal timing). In this scenario + // we must ignore the change as the change, whatever it may + // have been, is of no interest to us because we don't watch + // the file and furthermore the file does not even exist. + return; + } else if (!fi.exists()) { + fileExisted = false; + }; + emit q->changed(); + } }; FileWatch::FileWatch(const QString &file, QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); - d->start(file); + d = new Private(this); + d->start(file); } FileWatch::~FileWatch() { - delete d; + delete d; } QString FileWatch::fileName() const { - return d->fileName; + return d->fileName; } void FileWatch::setFileName(const QString &file) { - d->stop(); - d->start(file); + d->stop(); + d->start(file); } } diff --git a/src/support/logger.cpp b/src/support/logger.cpp --- a/src/support/logger.cpp +++ b/src/support/logger.cpp @@ -20,100 +20,94 @@ #include "qca_support.h" -namespace QCA { +namespace QCA +{ AbstractLogDevice::AbstractLogDevice(const QString &name, QObject *parent) : - QObject( parent ), m_name( name ) + QObject(parent), m_name(name) { } AbstractLogDevice::~AbstractLogDevice() {} QString AbstractLogDevice::name() const { - return m_name; + return m_name; } -void AbstractLogDevice::logTextMessage( const QString &message, Logger::Severity severity ) +void AbstractLogDevice::logTextMessage(const QString &message, Logger::Severity severity) { - Q_UNUSED( message ); - Q_UNUSED( severity ); + Q_UNUSED(message); + Q_UNUSED(severity); } -void AbstractLogDevice::logBinaryMessage( const QByteArray &blob, Logger::Severity severity ) +void AbstractLogDevice::logBinaryMessage(const QByteArray &blob, Logger::Severity severity) { - Q_UNUSED( blob ); - Q_UNUSED( severity ); + Q_UNUSED(blob); + Q_UNUSED(severity); } Logger::Logger() { - // d pointer? - m_logLevel = Logger::Notice; + // d pointer? + m_logLevel = Logger::Notice; } Logger::~Logger() { - // delete d; + // delete d; } QStringList Logger::currentLogDevices() const { - return m_loggerNames; + return m_loggerNames; } -void Logger::registerLogDevice(AbstractLogDevice* logger) +void Logger::registerLogDevice(AbstractLogDevice *logger) { - m_loggers.append( logger ); - m_loggerNames.append( logger->name() ); + m_loggers.append(logger); + m_loggerNames.append(logger->name()); } void Logger::unregisterLogDevice(const QString &loggerName) { - for ( int i = 0; i < m_loggers.size(); ++i ) - { - if ( m_loggers[i]->name() == loggerName ) - { - m_loggers.removeAt( i ); - --i; // we backstep, to make sure we check the new entry in this position. - } + for (int i = 0; i < m_loggers.size(); ++i) { + if (m_loggers[i]->name() == loggerName) { + m_loggers.removeAt(i); + --i; // we backstep, to make sure we check the new entry in this position. } - for ( int i = 0; i < m_loggerNames.size(); ++i ) - { - if ( m_loggerNames[i] == loggerName ) - { - m_loggerNames.removeAt( i ); - --i; // we backstep, to make sure we check the new entry in this position. - } + } + for (int i = 0; i < m_loggerNames.size(); ++i) { + if (m_loggerNames[i] == loggerName) { + m_loggerNames.removeAt(i); + --i; // we backstep, to make sure we check the new entry in this position. } + } } -void Logger::setLevel (Severity level) +void Logger::setLevel(Severity level) { - m_logLevel = level; + m_logLevel = level; } -void Logger::logTextMessage(const QString &message, Severity severity ) +void Logger::logTextMessage(const QString &message, Severity severity) { - if (severity <= level ()) { - for ( int i = 0; i < m_loggers.size(); ++i ) - { - m_loggers[i]->logTextMessage( message, severity ); - } - } + if (severity <= level()) { + for (int i = 0; i < m_loggers.size(); ++i) { + m_loggers[i]->logTextMessage(message, severity); + } + } } -void Logger::logBinaryMessage(const QByteArray &blob, Severity severity ) +void Logger::logBinaryMessage(const QByteArray &blob, Severity severity) { - if (severity <= level ()) { - for ( int i = 0; i < m_loggers.size(); ++i ) - { - m_loggers[i]->logBinaryMessage( blob, severity ); - } - } + if (severity <= level()) { + for (int i = 0; i < m_loggers.size(); ++i) { + m_loggers[i]->logBinaryMessage(blob, severity); + } + } } } - diff --git a/src/support/qpipe.cpp b/src/support/qpipe.cpp --- a/src/support/qpipe.cpp +++ b/src/support/qpipe.cpp @@ -66,203 +66,216 @@ #define PIPEEND_READBUF 16384 #define PIPEEND_READBUF_SEC 1024 -namespace QCA { +namespace QCA +{ #ifdef Q_OS_UNIX // adapted from qt Q_GLOBAL_STATIC(QMutex, ign_mutex) static bool ign_sigpipe = false; static void ignore_sigpipe() { - // Set to ignore SIGPIPE once only. + // Set to ignore SIGPIPE once only. //#if QT_VERSION < 0x040400 - QMutexLocker locker(ign_mutex()); - if(!ign_sigpipe) - { - ign_sigpipe = true; + QMutexLocker locker(ign_mutex()); + if (!ign_sigpipe) { + ign_sigpipe = true; //#else -// static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0); -// if(atom.testAndSetRelaxed(0, 1)) -// { +// static QBasicAtomicInt atom = Q_BASIC_ATOMIC_INITIALIZER(0); +// if(atom.testAndSetRelaxed(0, 1)) +// { //#endif - struct sigaction noaction; - memset(&noaction, 0, sizeof(noaction)); - noaction.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &noaction, 0); - } + struct sigaction noaction; + memset(&noaction, 0, sizeof(noaction)); + noaction.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &noaction, 0); + } } #endif #ifdef Q_OS_WIN static int pipe_dword_cap_to_int(DWORD dw) { - if(sizeof(int) <= sizeof(DWORD)) - return (int)((dw > INT_MAX) ? INT_MAX : dw); - else - return (int)dw; + if (sizeof(int) <= sizeof(DWORD)) { + return (int)((dw > INT_MAX) ? INT_MAX : dw); + } else { + return (int)dw; + } } static bool pipe_dword_overflows_int(DWORD dw) { - if(sizeof(int) <= sizeof(DWORD)) - return (dw > INT_MAX) ? true : false; - else - return false; + if (sizeof(int) <= sizeof(DWORD)) { + return (dw > INT_MAX) ? true : false; + } else { + return false; + } } #endif #ifdef Q_OS_UNIX static int pipe_size_t_cap_to_int(size_t size) { - if(sizeof(int) <= sizeof(size_t)) - return (int)((size > INT_MAX) ? INT_MAX : size); - else // maybe silly.. can int ever be larger than size_t? - return (int)size; + if (sizeof(int) <= sizeof(size_t)) { + return (int)((size > INT_MAX) ? INT_MAX : size); + } else { // maybe silly.. can int ever be larger than size_t? + return (int)size; + } } #endif static bool pipe_set_blocking(Q_PIPE_ID pipe, bool b) { #ifdef Q_OS_WIN - DWORD flags = 0; - if(!b) - flags |= PIPE_NOWAIT; - if(!SetNamedPipeHandleState(pipe, &flags, NULL, NULL)) - return false; - return true; + DWORD flags = 0; + if (!b) { + flags |= PIPE_NOWAIT; + } + if (!SetNamedPipeHandleState(pipe, &flags, NULL, NULL)) { + return false; + } + return true; #endif #ifdef Q_OS_UNIX - int flags = fcntl(pipe, F_GETFL); - if(!b) - flags |= O_NONBLOCK; - else - flags &= ~O_NONBLOCK; - if(fcntl(pipe, F_SETFL, flags) == -1) - return false; - return true; + int flags = fcntl(pipe, F_GETFL); + if (!b) { + flags |= O_NONBLOCK; + } else { + flags &= ~O_NONBLOCK; + } + if (fcntl(pipe, F_SETFL, flags) == -1) { + return false; + } + return true; #endif } // on windows, the pipe is closed and the new pipe is returned in newPipe static bool pipe_set_inheritable(Q_PIPE_ID pipe, bool b, Q_PIPE_ID *newPipe = 0) { #ifdef Q_OS_WIN - // windows is required to accept a new pipe id - if(!newPipe) - return false; - HANDLE h; - if(!DuplicateHandle(GetCurrentProcess(), pipe, GetCurrentProcess(), &h, 0, b, DUPLICATE_SAME_ACCESS)) - return false; - *newPipe = h; - return true; + // windows is required to accept a new pipe id + if (!newPipe) { + return false; + } + HANDLE h; + if (!DuplicateHandle(GetCurrentProcess(), pipe, GetCurrentProcess(), &h, 0, b, DUPLICATE_SAME_ACCESS)) { + return false; + } + *newPipe = h; + return true; #endif #ifdef Q_OS_UNIX - if(newPipe) - *newPipe = pipe; - int flags = fcntl(pipe, F_GETFD); - if(!b) - flags |= FD_CLOEXEC; - else - flags &= ~FD_CLOEXEC; - if(fcntl(pipe, F_SETFD, flags) == -1) - return false; - return true; + if (newPipe) { + *newPipe = pipe; + } + int flags = fcntl(pipe, F_GETFD); + if (!b) { + flags |= FD_CLOEXEC; + } else { + flags &= ~FD_CLOEXEC; + } + if (fcntl(pipe, F_SETFD, flags) == -1) { + return false; + } + return true; #endif } // returns number of bytes available static int pipe_read_avail(Q_PIPE_ID pipe) { - int bytesAvail = 0; + int bytesAvail = 0; #ifdef Q_OS_WIN - DWORD i = 0; - if(PeekNamedPipe(pipe, 0, 0, 0, &i, 0)) - bytesAvail = pipe_dword_cap_to_int(i); + DWORD i = 0; + if (PeekNamedPipe(pipe, 0, 0, 0, &i, 0)) { + bytesAvail = pipe_dword_cap_to_int(i); + } #endif #ifdef Q_OS_UNIX - size_t nbytes = 0; - if(ioctl(pipe, FIONREAD, (char *)&nbytes) >= 0) - bytesAvail = pipe_size_t_cap_to_int(nbytes); + size_t nbytes = 0; + if (ioctl(pipe, FIONREAD, (char *)&nbytes) >= 0) { + bytesAvail = pipe_size_t_cap_to_int(nbytes); + } #endif - return bytesAvail; + return bytesAvail; } // returns number of bytes actually read, no more than 'max'. // -1 on error. 0 means no data, NOT EOF. // note: even though this function looks like it can return data and EOF // at the same time, it never actually does. static int pipe_read(Q_PIPE_ID pipe, char *data, int max, bool *eof) { - int bytesRead = 0; - if(eof) - *eof = false; - if(max < 1) - return 0; + int bytesRead = 0; + if (eof) { + *eof = false; + } + if (max < 1) { + return 0; + } #ifdef Q_OS_WIN - DWORD maxread = max; - DWORD r = 0; - if(!ReadFile(pipe, data, maxread, &r, 0)) - { - DWORD err = GetLastError(); - if(err == ERROR_HANDLE_EOF) - { - if(eof) - *eof = true; - } - else if(err == ERROR_NO_DATA) - { - r = 0; - } - else - return -1; - } - bytesRead = (int)r; // safe to cast, since 'max' is signed + DWORD maxread = max; + DWORD r = 0; + if (!ReadFile(pipe, data, maxread, &r, 0)) { + DWORD err = GetLastError(); + if (err == ERROR_HANDLE_EOF) { + if (eof) { + *eof = true; + } + } else if (err == ERROR_NO_DATA) { + r = 0; + } else { + return -1; + } + } + bytesRead = (int)r; // safe to cast, since 'max' is signed #endif #ifdef Q_OS_UNIX - int r = 0; - int ret = read(pipe, data, max); - if(ret == -1) - { - if(errno != EAGAIN) - return -1; - } - else if(ret == 0) - { - if(eof) - *eof = true; - } - else - r = ret; - - bytesRead = r; -#endif - return bytesRead; + int r = 0; + int ret = read(pipe, data, max); + if (ret == -1) { + if (errno != EAGAIN) { + return -1; + } + } else if (ret == 0) { + if (eof) { + *eof = true; + } + } else { + r = ret; + } + + bytesRead = r; +#endif + return bytesRead; } // returns number of bytes actually written. // for blocking pipes, this should always be 'size'. // -1 on error. static int pipe_write(Q_PIPE_ID pipe, const char *data, int size) { #ifdef Q_OS_WIN - DWORD written; - if(!WriteFile(pipe, data, size, &written, 0)) - return -1; - return (int)written; // safe to cast, since 'size' is signed + DWORD written; + if (!WriteFile(pipe, data, size, &written, 0)) { + return -1; + } + return (int)written; // safe to cast, since 'size' is signed #endif #ifdef Q_OS_UNIX - ignore_sigpipe(); - int r = 0; - int ret = write(pipe, data, size); - if(ret == -1) - { - if(errno != EAGAIN) - return -1; - } - else - r = ret; - return r; + ignore_sigpipe(); + int r = 0; + int ret = write(pipe, data, size); + if (ret == -1) { + if (errno != EAGAIN) { + return -1; + } + } else { + r = ret; + } + return r; #endif } @@ -272,178 +285,179 @@ static bool pipe_is_a_console(Q_PIPE_ID pipe) { - DWORD mode; - if(GetConsoleMode(pipe, &mode)) - return true; - return false; + DWORD mode; + if (GetConsoleMode(pipe, &mode)) { + return true; + } + return false; } // returns the number of keypress events in the console input queue, // or -1 if there is an error (don't forget this!!) static int pipe_read_avail_console(Q_PIPE_ID pipe) { - DWORD count, i; - INPUT_RECORD *rec; - int n, icount, total; + DWORD count, i; + INPUT_RECORD *rec; + int n, icount, total; - // how many events are there? - if(!GetNumberOfConsoleInputEvents(pipe, &count)) - return -1; + // how many events are there? + if (!GetNumberOfConsoleInputEvents(pipe, &count)) { + return -1; + } - // peek them all - rec = (INPUT_RECORD *)malloc(count * sizeof(INPUT_RECORD)); - BOOL ret; + // peek them all + rec = (INPUT_RECORD *)malloc(count * sizeof(INPUT_RECORD)); + BOOL ret; #if QT_VERSION >= 0x050000 - ret = PeekConsoleInputW(pipe, rec, count, &i); + ret = PeekConsoleInputW(pipe, rec, count, &i); #else - QT_WA( - ret = PeekConsoleInputW(pipe, rec, count, &i); - , - ret = PeekConsoleInputA(pipe, rec, count, &i); - ) -#endif - if(!ret) - { - free(rec); - return -1; - } - - icount = pipe_dword_cap_to_int(i); // process only the amount returned - - // see which ones are normal keypress events - total = 0; - for(n = 0; n < icount; ++n) - { - if(rec[n].EventType == KEY_EVENT) - { - KEY_EVENT_RECORD *ke = &rec[n].Event.KeyEvent; - if(ke->bKeyDown && ke->uChar.AsciiChar != 0) - total += ke->wRepeatCount; - } - } - - free(rec); - return total; + QT_WA( + ret = PeekConsoleInputW(pipe, rec, count, &i); + , + ret = PeekConsoleInputA(pipe, rec, count, &i); + ) +#endif + if (!ret) { + free(rec); + return -1; + } + + icount = pipe_dword_cap_to_int(i); // process only the amount returned + + // see which ones are normal keypress events + total = 0; + for (n = 0; n < icount; ++n) { + if (rec[n].EventType == KEY_EVENT) { + KEY_EVENT_RECORD *ke = &rec[n].Event.KeyEvent; + if (ke->bKeyDown && ke->uChar.AsciiChar != 0) { + total += ke->wRepeatCount; + } + } + } + + free(rec); + return total; } // pass dec to keep a long-running decoder, else 0 static int pipe_read_console(Q_PIPE_ID pipe, ushort *data, int max, bool *eof, QTextDecoder *dec = 0) { - int n, size, count; - bool own_decoder; - - if(eof) - *eof = false; - if(max < 1) - return 0; - - count = pipe_read_avail_console(pipe); - if(count == -1) - return -1; - if(count == 0) - return 0; - - if(dec) - { - own_decoder = false; - } - else - { + int n, size, count; + bool own_decoder; + + if (eof) { + *eof = false; + } + if (max < 1) { + return 0; + } + + count = pipe_read_avail_console(pipe); + if (count == -1) { + return -1; + } + if (count == 0) { + return 0; + } + + if (dec) { + own_decoder = false; + } else { #if QT_VERSION >= 0x050000 - dec = 0; + dec = 0; #else - QT_WA( - dec = 0; - , - dec = QTextCodec::codecForLocale()->makeDecoder(); - ) -#endif - own_decoder = true; - } - - size = 0; - for(n = 0; n < count && size < max; ++n) - { - bool use_uni = true; - quint16 uni = 0; - quint8 ansi = 0; - - BOOL ret; - DWORD i; + QT_WA( + dec = 0; + , + dec = QTextCodec::codecForLocale()->makeDecoder(); + ) +#endif + own_decoder = true; + } + + size = 0; + for (n = 0; n < count && size < max; ++n) { + bool use_uni = true; + quint16 uni = 0; + quint8 ansi = 0; + + BOOL ret; + DWORD i; #if QT_VERSION >= 0x050000 - ret = ReadConsoleW(pipe, &uni, 1, &i, NULL); + ret = ReadConsoleW(pipe, &uni, 1, &i, NULL); #else - QT_WA( - ret = ReadConsoleW(pipe, &uni, 1, &i, NULL); - , - ret = ReadConsoleA(pipe, &ansi, 1, &i, NULL); - use_uni = false; - ) -#endif - if(!ret) - { - // if the first read is an error, then report error - if(n == 0) - { - delete dec; - return -1; - } - // if we have some data, don't count this as an error. - // we'll probably get it again next time around... - else - break; - } - - QString substr; - if(use_uni) - substr = QChar(uni); - else - substr = dec->toUnicode((const char *)&ansi, 1); - - for(int k = 0; k < substr.length() && size < max; ++k) - { - QChar c = substr[k]; - if(c == QChar(0x1A)) // EOF? - { - if(eof) - *eof = true; - break; - } - data[size++] = substr[k].unicode(); - } - } - if(own_decoder) - delete dec; - - return size; + QT_WA( + ret = ReadConsoleW(pipe, &uni, 1, &i, NULL); + , + ret = ReadConsoleA(pipe, &ansi, 1, &i, NULL); + use_uni = false; + ) +#endif + if (!ret) { + // if the first read is an error, then report error + if (n == 0) { + delete dec; + return -1; + } + // if we have some data, don't count this as an error. + // we'll probably get it again next time around... + else { + break; + } + } + + QString substr; + if (use_uni) { + substr = QChar(uni); + } else { + substr = dec->toUnicode((const char *)&ansi, 1); + } + + for (int k = 0; k < substr.length() && size < max; ++k) { + QChar c = substr[k]; + if (c == QChar(0x1A)) { // EOF? + if (eof) { + *eof = true; + } + break; + } + data[size++] = substr[k].unicode(); + } + } + if (own_decoder) { + delete dec; + } + + return size; } static int pipe_write_console(Q_PIPE_ID pipe, const ushort *data, int size) { - DWORD i; - BOOL ret; + DWORD i; + BOOL ret; #if QT_VERSION >= 0x050000 - ret = WriteConsoleW(pipe, data, size, &i, NULL); + ret = WriteConsoleW(pipe, data, size, &i, NULL); #else - QT_WA( - ret = WriteConsoleW(pipe, data, size, &i, NULL); - , - // Note: we lose security by converting to QString here, but - // who really cares if we're writing to a *display* ? :) - QByteArray out = QString::fromUtf16(data, size).toLocal8Bit(); - ret = WriteConsoleA(pipe, out.data(), out.size(), &i, NULL); - if(ret) - { - // convert number of bytes to number of unicode chars - i = (DWORD)QString::fromLocal8Bit(out.mid(0, i)).length(); - if(pipe_dword_overflows_int(i)) - return -1; - } - ) -#endif - if(!ret) - return -1; - return (int)i; // safe to cast since 'size' is signed + QT_WA( + ret = WriteConsoleW(pipe, data, size, &i, NULL); + , + // Note: we lose security by converting to QString here, but + // who really cares if we're writing to a *display* ? :) + QByteArray out = QString::fromUtf16(data, size).toLocal8Bit(); + ret = WriteConsoleA(pipe, out.data(), out.size(), &i, NULL); + if (ret) { + // convert number of bytes to number of unicode chars + i = (DWORD)QString::fromLocal8Bit(out.mid(0, i)).length(); + if (pipe_dword_overflows_int(i)) { + return -1; + } + } + ) +#endif + if (!ret) { + return -1; + } + return (int)i; // safe to cast since 'size' is signed } #endif @@ -466,477 +480,470 @@ //---------------------------------------------------------------------------- class QPipeWriter : public QThread { - Q_OBJECT + Q_OBJECT public: - QPipeWriter(QObject *parent = 0) : QThread(parent) - { - } + QPipeWriter(QObject *parent = 0) : QThread(parent) + { + } - virtual ~QPipeWriter() - { - } + virtual ~QPipeWriter() + { + } - // start - virtual void start() = 0; + // start + virtual void start() = 0; - // stop, and return number of bytes written so far - virtual int stop() = 0; + // stop, and return number of bytes written so far + virtual int stop() = 0; - // data pointer needs to remain until canWrite is emitted - virtual int write(const char *data, int size) = 0; + // data pointer needs to remain until canWrite is emitted + virtual int write(const char *data, int size) = 0; signals: - // result values: - // = 0 : success - // = -1 : error - void canWrite(int result, int bytesWritten); + // result values: + // = 0 : success + // = -1 : error + void canWrite(int result, int bytesWritten); protected: - virtual void run() - { - // implement a default to satisfy the polling subclass - } + virtual void run() + { + // implement a default to satisfy the polling subclass + } }; //---------------------------------------------------------------------------- // QPipeReader //---------------------------------------------------------------------------- class QPipeReader : public QThread { - Q_OBJECT + Q_OBJECT public: - QPipeReader(QObject *parent = 0) : QThread(parent) - { - } + QPipeReader(QObject *parent = 0) : QThread(parent) + { + } - virtual ~QPipeReader() - { - } + virtual ~QPipeReader() + { + } - // start - virtual void start() = 0; + // start + virtual void start() = 0; - // to be called after every read - virtual void resume() = 0; + // to be called after every read + virtual void resume() = 0; signals: - // result values: - // >= 0 : readAhead - // = -1 : atEnd - // = -2 : atError - // = -3 : data available, but no readAhead - void canRead(int result); + // result values: + // >= 0 : readAhead + // = -1 : atEnd + // = -2 : atError + // = -3 : data available, but no readAhead + void canRead(int result); protected: - virtual void run() - { - // implement a default to satisfy the polling subclass - } + virtual void run() + { + // implement a default to satisfy the polling subclass + } }; //---------------------------------------------------------------------------- // QPipeWriterThread //---------------------------------------------------------------------------- class QPipeWriterThread : public QPipeWriter { - Q_OBJECT + Q_OBJECT public: - Q_PIPE_ID pipe; - QMutex m; - QWaitCondition w; - bool do_quit; - const char *data; - int size; - - QPipeWriterThread(Q_PIPE_ID id, QObject *parent = 0) : QPipeWriter(parent) - { - do_quit = false; - data = 0; - connect(this, SIGNAL(canWrite_p(int, int)), SIGNAL(canWrite(int, int))); - DuplicateHandle(GetCurrentProcess(), id, GetCurrentProcess(), &pipe, 0, false, DUPLICATE_SAME_ACCESS); - } - - virtual ~QPipeWriterThread() - { - stop(); - CloseHandle(pipe); - } - - virtual void start() - { - pipe_set_blocking(pipe, true); - QThread::start(); - } - - virtual int stop() - { - if(isRunning()) - { - m.lock(); - do_quit = true; - w.wakeOne(); - m.unlock(); - if(!wait(100)) - terminate(); - do_quit = false; - data = 0; - } - return size; - } - - virtual int write(const char *_data, int _size) - { - if(!isRunning()) - return -1; - - QMutexLocker locker(&m); - if(data) - return 0; - - data = _data; - size = _size; - w.wakeOne(); - return _size; - } + Q_PIPE_ID pipe; + QMutex m; + QWaitCondition w; + bool do_quit; + const char *data; + int size; + + QPipeWriterThread(Q_PIPE_ID id, QObject *parent = 0) : QPipeWriter(parent) + { + do_quit = false; + data = 0; + connect(this, SIGNAL(canWrite_p(int,int)), SIGNAL(canWrite(int,int))); + DuplicateHandle(GetCurrentProcess(), id, GetCurrentProcess(), &pipe, 0, false, DUPLICATE_SAME_ACCESS); + } + + virtual ~QPipeWriterThread() + { + stop(); + CloseHandle(pipe); + } + + virtual void start() + { + pipe_set_blocking(pipe, true); + QThread::start(); + } + + virtual int stop() + { + if (isRunning()) { + m.lock(); + do_quit = true; + w.wakeOne(); + m.unlock(); + if (!wait(100)) { + terminate(); + } + do_quit = false; + data = 0; + } + return size; + } + + virtual int write(const char *_data, int _size) + { + if (!isRunning()) { + return -1; + } + + QMutexLocker locker(&m); + if (data) { + return 0; + } + + data = _data; + size = _size; + w.wakeOne(); + return _size; + } protected: - virtual void run() - { - while(1) - { - m.lock(); + virtual void run() + { + while (1) { + m.lock(); - while(!data && !do_quit) - w.wait(&m); + while (!data && !do_quit) { + w.wait(&m); + } - if(do_quit) - { - m.unlock(); - break; - } + if (do_quit) { + m.unlock(); + break; + } - const char *p = data; - int len = size; + const char *p = data; + int len = size; - m.unlock(); + m.unlock(); - int ret = internalWrite(p, len); + int ret = internalWrite(p, len); - m.lock(); - data = 0; - size = ret; - m.unlock(); + m.lock(); + data = 0; + size = ret; + m.unlock(); - emit canWrite_p(ret < len ? -1 : 0, ret); - } - } + emit canWrite_p(ret < len ? -1 : 0, ret); + } + } private: - // attempts to write len bytes. value returned is number of bytes written. - // any return value less than len means a write error was encountered - int internalWrite(const char *p, int len) - { - int total = 0; - while(total < len) - { - m.lock(); - if(do_quit) - { - m.unlock(); - return 0; - } - m.unlock(); - - int ret = pipe_write(pipe, p + total, qMin(PIPEWRITER_BLOCK, len - total)); - if(ret == -1) - { - // from qt, don't know why - if(GetLastError() == 0xE8) // NT_STATUS_INVALID_USER_BUFFER - { - // give the os a rest - msleep(100); - continue; - } - - // on any other error, end thread - return total; - } - total += ret; - } - return total; - } + // attempts to write len bytes. value returned is number of bytes written. + // any return value less than len means a write error was encountered + int internalWrite(const char *p, int len) + { + int total = 0; + while (total < len) { + m.lock(); + if (do_quit) { + m.unlock(); + return 0; + } + m.unlock(); + + int ret = pipe_write(pipe, p + total, qMin(PIPEWRITER_BLOCK, len - total)); + if (ret == -1) { + // from qt, don't know why + if (GetLastError() == 0xE8) { // NT_STATUS_INVALID_USER_BUFFER + // give the os a rest + msleep(100); + continue; + } + + // on any other error, end thread + return total; + } + total += ret; + } + return total; + } signals: - void canWrite_p(int result, int bytesWritten); + void canWrite_p(int result, int bytesWritten); }; //---------------------------------------------------------------------------- // QPipeWriterPoll //---------------------------------------------------------------------------- class QPipeWriterPoll : public QPipeWriter { - Q_OBJECT + Q_OBJECT public: - Q_PIPE_ID pipe; - const char *data; - int size; - SafeTimer timer; - int total; - - QPipeWriterPoll(Q_PIPE_ID id, QObject *parent = 0) : QPipeWriter(parent), timer(this) - { - pipe = id; - data = 0; - connect(&timer, SIGNAL(timeout()), SLOT(tryNextWrite())); - } - - virtual ~QPipeWriterPoll() - { - } - - virtual void start() - { - pipe_set_blocking(pipe, false); - } - - // return number of bytes written - virtual int stop() - { - timer.stop(); - data = 0; - return total; - } - - // data pointer needs to remain until canWrite is emitted - virtual int write(const char *_data, int _size) - { - total = 0; - data = _data; - size = _size; - timer.start(0); // write at next event loop - return _size; - } + Q_PIPE_ID pipe; + const char *data; + int size; + SafeTimer timer; + int total; + + QPipeWriterPoll(Q_PIPE_ID id, QObject *parent = 0) : QPipeWriter(parent), timer(this) + { + pipe = id; + data = 0; + connect(&timer, SIGNAL(timeout()), SLOT(tryNextWrite())); + } + + virtual ~QPipeWriterPoll() + { + } + + virtual void start() + { + pipe_set_blocking(pipe, false); + } + + // return number of bytes written + virtual int stop() + { + timer.stop(); + data = 0; + return total; + } + + // data pointer needs to remain until canWrite is emitted + virtual int write(const char *_data, int _size) + { + total = 0; + data = _data; + size = _size; + timer.start(0); // write at next event loop + return _size; + } private slots: - void tryNextWrite() - { - int written = pipe_write(pipe, data + total, size - total); - bool error = false; - if(written == -1) - { - error = true; - written = 0; // no bytes written on error - - // from qt, they don't count it as fatal - if(GetLastError() == 0xE8) // NT_STATUS_INVALID_USER_BUFFER - error = false; - } - - total += written; - if(error || total == size) - { - timer.stop(); - data = 0; - emit canWrite(error ? -1 : 0, total); - return; - } - - timer.setInterval(PIPEWRITER_POLL); - } + void tryNextWrite() + { + int written = pipe_write(pipe, data + total, size - total); + bool error = false; + if (written == -1) { + error = true; + written = 0; // no bytes written on error + + // from qt, they don't count it as fatal + if (GetLastError() == 0xE8) { // NT_STATUS_INVALID_USER_BUFFER + error = false; + } + } + + total += written; + if (error || total == size) { + timer.stop(); + data = 0; + emit canWrite(error ? -1 : 0, total); + return; + } + + timer.setInterval(PIPEWRITER_POLL); + } }; //---------------------------------------------------------------------------- // QPipeReaderThread //---------------------------------------------------------------------------- class QPipeReaderThread : public QPipeReader { - Q_OBJECT + Q_OBJECT public: - Q_PIPE_ID pipe; - QMutex m; - QWaitCondition w; - bool do_quit, active; - - QPipeReaderThread(Q_PIPE_ID id, QObject *parent = 0) : QPipeReader(parent) - { - do_quit = false; - active = true; - connect(this, SIGNAL(canRead_p(int)), SIGNAL(canRead(int))); - DuplicateHandle(GetCurrentProcess(), id, GetCurrentProcess(), &pipe, 0, false, DUPLICATE_SAME_ACCESS); - } - - virtual ~QPipeReaderThread() - { - if(isRunning()) - { - m.lock(); - do_quit = true; - w.wakeOne(); - m.unlock(); - if(!wait(100)) - terminate(); - } - CloseHandle(pipe); - } - - virtual void start() - { - pipe_set_blocking(pipe, true); - QThread::start(); - } - - virtual void resume() - { - QMutexLocker locker(&m); - pipe_set_blocking(pipe, true); - active = true; - w.wakeOne(); - } + Q_PIPE_ID pipe; + QMutex m; + QWaitCondition w; + bool do_quit, active; + + QPipeReaderThread(Q_PIPE_ID id, QObject *parent = 0) : QPipeReader(parent) + { + do_quit = false; + active = true; + connect(this, SIGNAL(canRead_p(int)), SIGNAL(canRead(int))); + DuplicateHandle(GetCurrentProcess(), id, GetCurrentProcess(), &pipe, 0, false, DUPLICATE_SAME_ACCESS); + } + + virtual ~QPipeReaderThread() + { + if (isRunning()) { + m.lock(); + do_quit = true; + w.wakeOne(); + m.unlock(); + if (!wait(100)) { + terminate(); + } + } + CloseHandle(pipe); + } + + virtual void start() + { + pipe_set_blocking(pipe, true); + QThread::start(); + } + + virtual void resume() + { + QMutexLocker locker(&m); + pipe_set_blocking(pipe, true); + active = true; + w.wakeOne(); + } protected: - virtual void run() - { - while(1) - { - m.lock(); - - while(!active && !do_quit) - w.wait(&m); - - if(do_quit) - { - m.unlock(); - break; - } - - m.unlock(); - - while(1) - { - unsigned char c; - bool done; - int ret = pipe_read(pipe, (char *)&c, 1, &done); - if(done || ret != 0) // eof, error, or data? - { - int result; - - if(done) // we got EOF? - result = -1; - else if(ret == -1) // we got an error? - result = -2; - else if(ret >= 1) // we got some data?? queue it - result = c; - else // will never happen - result = -2; - - m.lock(); - active = false; - pipe_set_blocking(pipe, false); - m.unlock(); - - emit canRead_p(result); - break; - } - } - } - } + virtual void run() + { + while (1) { + m.lock(); + + while (!active && !do_quit) { + w.wait(&m); + } + + if (do_quit) { + m.unlock(); + break; + } + + m.unlock(); + + while (1) { + unsigned char c; + bool done; + int ret = pipe_read(pipe, (char *)&c, 1, &done); + if (done || ret != 0) { // eof, error, or data? + int result; + + if (done) { // we got EOF? + result = -1; + } else if (ret == -1) { // we got an error? + result = -2; + } else if (ret >= 1) { // we got some data?? queue it + result = c; + } else { // will never happen + result = -2; + } + + m.lock(); + active = false; + pipe_set_blocking(pipe, false); + m.unlock(); + + emit canRead_p(result); + break; + } + } + } + } signals: - void canRead_p(int result); + void canRead_p(int result); }; //---------------------------------------------------------------------------- // QPipeReaderPoll //---------------------------------------------------------------------------- class QPipeReaderPoll : public QPipeReader { - Q_OBJECT + Q_OBJECT public: - Q_PIPE_ID pipe; - SafeTimer timer; - bool consoleMode; - - QPipeReaderPoll(Q_PIPE_ID id, QObject *parent = 0) : QPipeReader(parent), timer(this) - { - pipe = id; - connect(&timer, SIGNAL(timeout()), SLOT(tryRead())); - } - - virtual ~QPipeReaderPoll() - { - } - - virtual void start() - { - pipe_set_blocking(pipe, false); - consoleMode = pipe_is_a_console(pipe); - resume(); - } - - virtual void resume() - { - timer.start(0); - } + Q_PIPE_ID pipe; + SafeTimer timer; + bool consoleMode; + + QPipeReaderPoll(Q_PIPE_ID id, QObject *parent = 0) : QPipeReader(parent), timer(this) + { + pipe = id; + connect(&timer, SIGNAL(timeout()), SLOT(tryRead())); + } + + virtual ~QPipeReaderPoll() + { + } + + virtual void start() + { + pipe_set_blocking(pipe, false); + consoleMode = pipe_is_a_console(pipe); + resume(); + } + + virtual void resume() + { + timer.start(0); + } private slots: - void tryRead() - { - if(consoleMode) - tryReadConsole(); - else - tryReadPipe(); - } + void tryRead() + { + if (consoleMode) { + tryReadConsole(); + } else { + tryReadPipe(); + } + } private: - void tryReadPipe() - { - // is there data available for reading? if so, signal. - int bytes = pipe_read_avail(pipe); - if(bytes > 0) - { - timer.stop(); - emit canRead(-3); // no readAhead - return; - } - - // no data available? probe for EOF/error - unsigned char c; - bool done; - int ret = pipe_read(pipe, (char *)&c, 1, &done); - if(done || ret != 0) // eof, error, or data? - { - int result; - - if(done) // we got EOF? - result = -1; - else if(ret == -1) // we got an error? - result = -2; - else if(ret >= 1) // we got some data?? queue it - result = c; - else // will never happen - result = -2; - - timer.stop(); - emit canRead(result); - return; - } - - timer.setInterval(PIPEREADER_POLL); - } - - void tryReadConsole() - { - // is there data available for reading? if so, signal. - int count = pipe_read_avail_console(pipe); - if(count > 0) - { - timer.stop(); - emit canRead(-3); // no readAhead - return; - } - - timer.setInterval(PIPEREADER_POLL); - } + void tryReadPipe() + { + // is there data available for reading? if so, signal. + int bytes = pipe_read_avail(pipe); + if (bytes > 0) { + timer.stop(); + emit canRead(-3); // no readAhead + return; + } + + // no data available? probe for EOF/error + unsigned char c; + bool done; + int ret = pipe_read(pipe, (char *)&c, 1, &done); + if (done || ret != 0) { // eof, error, or data? + int result; + + if (done) { // we got EOF? + result = -1; + } else if (ret == -1) { // we got an error? + result = -2; + } else if (ret >= 1) { // we got some data?? queue it + result = c; + } else { // will never happen + result = -2; + } + + timer.stop(); + emit canRead(result); + return; + } + + timer.setInterval(PIPEREADER_POLL); + } + + void tryReadConsole() + { + // is there data available for reading? if so, signal. + int count = pipe_read_avail_console(pipe); + if (count > 0) { + timer.stop(); + emit canRead(-3); // no readAhead + return; + } + + timer.setInterval(PIPEREADER_POLL); + } }; // end of windows pipe writer/reader implementations @@ -948,1170 +955,1153 @@ //---------------------------------------------------------------------------- class QPipeDevice::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - QPipeDevice *q; - Q_PIPE_ID pipe; - QPipeDevice::Type type; - bool enabled; - bool blockReadNotify; - bool canWrite; - int writeResult; - int lastTaken, lastWritten; + QPipeDevice *q; + Q_PIPE_ID pipe; + QPipeDevice::Type type; + bool enabled; + bool blockReadNotify; + bool canWrite; + int writeResult; + int lastTaken, lastWritten; #ifdef Q_OS_WIN - bool atEnd, atError, forceNotify; - int readAhead; - SafeTimer *readTimer; - QTextDecoder *dec; - bool consoleMode; - QPipeWriter *pipeWriter; - QPipeReader *pipeReader; + bool atEnd, atError, forceNotify; + int readAhead; + SafeTimer *readTimer; + QTextDecoder *dec; + bool consoleMode; + QPipeWriter *pipeWriter; + QPipeReader *pipeReader; #endif #ifdef Q_OS_UNIX - SafeSocketNotifier *sn_read, *sn_write; + SafeSocketNotifier *sn_read, *sn_write; #endif - Private(QPipeDevice *_q) : QObject(_q), q(_q), pipe(INVALID_Q_PIPE_ID) - { + Private(QPipeDevice *_q) : QObject(_q), q(_q), pipe(INVALID_Q_PIPE_ID) + { #ifdef Q_OS_WIN - readTimer = 0; - pipeWriter = 0; - pipeReader = 0; - dec = 0; + readTimer = 0; + pipeWriter = 0; + pipeReader = 0; + dec = 0; #endif #ifdef Q_OS_UNIX - sn_read = 0; - sn_write = 0; + sn_read = 0; + sn_write = 0; #endif - } + } - ~Private() - { - reset(); - } + ~Private() + { + reset(); + } - void reset() - { + void reset() + { #ifdef Q_OS_WIN - atEnd = false; - atError = false; - forceNotify = false; - readAhead = -1; - delete readTimer; - readTimer = 0; - delete pipeWriter; - pipeWriter = 0; - delete pipeReader; - pipeReader = 0; - delete dec; - dec = 0; - consoleMode = false; + atEnd = false; + atError = false; + forceNotify = false; + readAhead = -1; + delete readTimer; + readTimer = 0; + delete pipeWriter; + pipeWriter = 0; + delete pipeReader; + pipeReader = 0; + delete dec; + dec = 0; + consoleMode = false; #endif #ifdef Q_OS_UNIX - delete sn_read; - sn_read = 0; - delete sn_write; - sn_write = 0; + delete sn_read; + sn_read = 0; + delete sn_write; + sn_write = 0; #endif - if(pipe != INVALID_Q_PIPE_ID) - { + if (pipe != INVALID_Q_PIPE_ID) { #ifdef Q_OS_WIN - CloseHandle(pipe); + CloseHandle(pipe); #endif #ifdef Q_OS_UNIX - ::close(pipe); + ::close(pipe); #endif - pipe = INVALID_Q_PIPE_ID; - } + pipe = INVALID_Q_PIPE_ID; + } - enabled = false; - blockReadNotify = false; - canWrite = true; - writeResult = -1; - } + enabled = false; + blockReadNotify = false; + canWrite = true; + writeResult = -1; + } - void setup(Q_PIPE_ID id, QPipeDevice::Type _type) - { - pipe = id; - type = _type; - } + void setup(Q_PIPE_ID id, QPipeDevice::Type _type) + { + pipe = id; + type = _type; + } - void enable() - { - if(enabled) - return; + void enable() + { + if (enabled) { + return; + } - enabled = true; + enabled = true; - if(type == QPipeDevice::Read) - { + if (type == QPipeDevice::Read) { #ifdef Q_OS_WIN - // for windows, the blocking mode is chosen by the QPipeReader + // for windows, the blocking mode is chosen by the QPipeReader - // console might need a decoder - if(consoleMode) - { + // console might need a decoder + if (consoleMode) { #if QT_VERSION >= 0x050000 - dec = 0; + dec = 0; #else - QT_WA( - dec = 0; - , - dec = QTextCodec::codecForLocale()->makeDecoder(); - ) + QT_WA( + dec = 0; + , + dec = QTextCodec::codecForLocale()->makeDecoder(); + ) #endif - } + } - // pipe reader + // pipe reader #ifdef USE_POLL - pipeReader = new QPipeReaderPoll(pipe, this); + pipeReader = new QPipeReaderPoll(pipe, this); #else - // console always polls, no matter what - if(consoleMode) - pipeReader = new QPipeReaderPoll(pipe, this); - else - pipeReader = new QPipeReaderThread(pipe, this); + // console always polls, no matter what + if (consoleMode) { + pipeReader = new QPipeReaderPoll(pipe, this); + } else { + pipeReader = new QPipeReaderThread(pipe, this); + } #endif - connect(pipeReader, SIGNAL(canRead(int)), this, SLOT(pr_canRead(int))); - pipeReader->start(); + connect(pipeReader, SIGNAL(canRead(int)), this, SLOT(pr_canRead(int))); + pipeReader->start(); - // polling timer - readTimer = new SafeTimer(this); - connect(readTimer, SIGNAL(timeout()), SLOT(t_timeout())); + // polling timer + readTimer = new SafeTimer(this); + connect(readTimer, SIGNAL(timeout()), SLOT(t_timeout())); - // updated: now that we have pipeReader, this no longer - // polls for data. it only does delayed singleshot - // notifications. - readTimer->setSingleShot(true); + // updated: now that we have pipeReader, this no longer + // polls for data. it only does delayed singleshot + // notifications. + readTimer->setSingleShot(true); #endif #ifdef Q_OS_UNIX - pipe_set_blocking(pipe, false); + pipe_set_blocking(pipe, false); - // socket notifier - sn_read = new SafeSocketNotifier(pipe, QSocketNotifier::Read, this); - connect(sn_read, SIGNAL(activated(int)), SLOT(sn_read_activated(int))); + // socket notifier + sn_read = new SafeSocketNotifier(pipe, QSocketNotifier::Read, this); + connect(sn_read, SIGNAL(activated(int)), SLOT(sn_read_activated(int))); #endif - } - else - { - // for windows, the blocking mode is chosen by the QPipeWriter + } else { + // for windows, the blocking mode is chosen by the QPipeWriter #ifdef Q_OS_UNIX - pipe_set_blocking(pipe, false); + pipe_set_blocking(pipe, false); - // socket notifier - sn_write = new SafeSocketNotifier(pipe, QSocketNotifier::Write, this); - connect(sn_write, SIGNAL(activated(int)), SLOT(sn_write_activated(int))); - sn_write->setEnabled(false); + // socket notifier + sn_write = new SafeSocketNotifier(pipe, QSocketNotifier::Write, this); + connect(sn_write, SIGNAL(activated(int)), SLOT(sn_write_activated(int))); + sn_write->setEnabled(false); #endif - } - } + } + } public slots: - void t_timeout() - { + void t_timeout() + { #ifdef Q_OS_WIN - if(blockReadNotify) - return; - - // were we forced to notify? this can happen if we want to - // spread out results across two reads. whatever caused - // the forceNotify already knows what to do, so all we do - // is signal. - if(forceNotify) - { - forceNotify = false; - blockReadNotify = true; - emit q->notify(); - return; - } -#endif - } - - void pw_canWrite(int result, int bytesWritten) - { + if (blockReadNotify) { + return; + } + + // were we forced to notify? this can happen if we want to + // spread out results across two reads. whatever caused + // the forceNotify already knows what to do, so all we do + // is signal. + if (forceNotify) { + forceNotify = false; + blockReadNotify = true; + emit q->notify(); + return; + } +#endif + } + + void pw_canWrite(int result, int bytesWritten) + { #ifdef Q_OS_WIN - if(result == 0) - { - writeResult = 0; - lastWritten = lastTaken; // success means all bytes - } - else - { - writeResult = -1; - lastWritten = bytesWritten; - } - - canWrite = true; - emit q->notify(); + if (result == 0) { + writeResult = 0; + lastWritten = lastTaken; // success means all bytes + } else { + writeResult = -1; + lastWritten = bytesWritten; + } + + canWrite = true; + emit q->notify(); #else - Q_UNUSED(result); - Q_UNUSED(bytesWritten); + Q_UNUSED(result); + Q_UNUSED(bytesWritten); #endif - } + } - void pr_canRead(int result) - { + void pr_canRead(int result) + { #ifdef Q_OS_WIN - blockReadNotify = true; - if(result == -1) - atEnd = true; - else if(result == -2) - atError = true; - else if(result != -3) - readAhead = result; - emit q->notify(); + blockReadNotify = true; + if (result == -1) { + atEnd = true; + } else if (result == -2) { + atError = true; + } else if (result != -3) { + readAhead = result; + } + emit q->notify(); #else - Q_UNUSED(result); + Q_UNUSED(result); #endif - } + } - void sn_read_activated(int) - { + void sn_read_activated(int) + { #ifdef Q_OS_UNIX - if(blockReadNotify) - return; + if (blockReadNotify) { + return; + } - blockReadNotify = true; - emit q->notify(); + blockReadNotify = true; + emit q->notify(); #endif - } + } - void sn_write_activated(int) - { + void sn_write_activated(int) + { #ifdef Q_OS_UNIX - writeResult = 0; - lastWritten = lastTaken; + writeResult = 0; + lastWritten = lastTaken; - canWrite = true; - sn_write->setEnabled(false); - emit q->notify(); + canWrite = true; + sn_write->setEnabled(false); + emit q->notify(); #endif - } + } }; QPipeDevice::QPipeDevice(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); + d = new Private(this); } QPipeDevice::~QPipeDevice() { - delete d; + delete d; } QPipeDevice::Type QPipeDevice::type() const { - return d->type; + return d->type; } bool QPipeDevice::isValid() const { - return (d->pipe != INVALID_Q_PIPE_ID); + return (d->pipe != INVALID_Q_PIPE_ID); } Q_PIPE_ID QPipeDevice::id() const { - return d->pipe; + return d->pipe; } int QPipeDevice::idAsInt() const { #ifdef Q_OS_WIN - DWORD dw; - memcpy(&dw, &d->pipe, sizeof(DWORD)); - return (int)dw; // FIXME? assumes handle value fits in signed int + DWORD dw; + memcpy(&dw, &d->pipe, sizeof(DWORD)); + return (int)dw; // FIXME? assumes handle value fits in signed int #endif #ifdef Q_OS_UNIX - return d->pipe; + return d->pipe; #endif } void QPipeDevice::take(Q_PIPE_ID id, Type t) { - close(); - d->setup(id, t); + close(); + d->setup(id, t); } void QPipeDevice::enable() { #ifdef Q_OS_WIN - d->consoleMode = pipe_is_a_console(d->pipe); + d->consoleMode = pipe_is_a_console(d->pipe); #endif - d->enable(); + d->enable(); } void QPipeDevice::close() { - d->reset(); + d->reset(); } void QPipeDevice::release() { - d->pipe = INVALID_Q_PIPE_ID; - d->reset(); + d->pipe = INVALID_Q_PIPE_ID; + d->reset(); } bool QPipeDevice::setInheritable(bool enabled) { #ifdef Q_OS_WIN - Q_PIPE_ID newPipe; - if(!pipe_set_inheritable(d->pipe, enabled, &newPipe)) - return false; - d->pipe = newPipe; + Q_PIPE_ID newPipe; + if (!pipe_set_inheritable(d->pipe, enabled, &newPipe)) { + return false; + } + d->pipe = newPipe; #ifdef USE_POLL - if(d->pipeReader) - static_cast(d->pipeReader)->pipe = d->pipe; - if(d->pipeWriter) - static_cast(d->pipeWriter)->pipe = d->pipe; + if (d->pipeReader) { + static_cast(d->pipeReader)->pipe = d->pipe; + } + if (d->pipeWriter) { + static_cast(d->pipeWriter)->pipe = d->pipe; + } #endif - return true; + return true; #endif #ifdef Q_OS_UNIX - return pipe_set_inheritable(d->pipe, enabled, 0); + return pipe_set_inheritable(d->pipe, enabled, 0); #endif } int QPipeDevice::bytesAvailable() const { - int n; + int n; #ifdef Q_OS_WIN - if(d->consoleMode) - n = pipe_read_avail_console(d->pipe); - else - n = pipe_read_avail(d->pipe); - if(d->readAhead != -1) - ++n; + if (d->consoleMode) { + n = pipe_read_avail_console(d->pipe); + } else { + n = pipe_read_avail(d->pipe); + } + if (d->readAhead != -1) { + ++n; + } #else - n = pipe_read_avail(d->pipe); + n = pipe_read_avail(d->pipe); #endif - return n; + return n; } int QPipeDevice::read(char *data, int maxsize) { - if(d->type != QPipeDevice::Read) - return -1; + if (d->type != QPipeDevice::Read) { + return -1; + } - // must read at least 1 byte - if(maxsize < 1) - return -1; + // must read at least 1 byte + if (maxsize < 1) { + return -1; + } #ifdef Q_OS_WIN - // for windows console: - // the number of bytes in utf8 can exceed the number of actual - // characters it represents. to be safe, we'll assume that - // utf8 could outnumber characters X:1. this does mean that - // the maxsize parameter needs to be at least X to do - // anything. (X = CONSOLE_CHAREXPAND) - if(d->consoleMode && maxsize < CONSOLE_CHAREXPAND) - return -1; + // for windows console: + // the number of bytes in utf8 can exceed the number of actual + // characters it represents. to be safe, we'll assume that + // utf8 could outnumber characters X:1. this does mean that + // the maxsize parameter needs to be at least X to do + // anything. (X = CONSOLE_CHAREXPAND) + if (d->consoleMode && maxsize < CONSOLE_CHAREXPAND) { + return -1; + } - // for resuming the pipeReader - bool wasBlocked = d->blockReadNotify; + // for resuming the pipeReader + bool wasBlocked = d->blockReadNotify; #endif - d->blockReadNotify = false; + d->blockReadNotify = false; #ifdef Q_OS_WIN - // predetermined results - if(d->atEnd) - { - close(); - return 0; - } - if(d->atError) - { - close(); - return -1; - } - - int offset = 0; - int size = maxsize; - - // prepend readAhead if we have it - if(d->readAhead != -1) - { - unsigned char c = (unsigned char)d->readAhead; - d->readAhead = -1; - memcpy(&data[0], &c, 1); - ++offset; - --size; - - // readAhead was enough data for the caller? - if(size == 0) - { - if(wasBlocked) - d->pipeReader->resume(); - return offset; - } - } - - // read from the pipe now - bool done; - int ret; - if(d->consoleMode) - { - // read a fraction of the number of characters as requested, - // to guarantee the result fits - int num = size / CONSOLE_CHAREXPAND; + // predetermined results + if (d->atEnd) { + close(); + return 0; + } + if (d->atError) { + close(); + return -1; + } + + int offset = 0; + int size = maxsize; + + // prepend readAhead if we have it + if (d->readAhead != -1) { + unsigned char c = (unsigned char)d->readAhead; + d->readAhead = -1; + memcpy(&data[0], &c, 1); + ++offset; + --size; + + // readAhead was enough data for the caller? + if (size == 0) { + if (wasBlocked) { + d->pipeReader->resume(); + } + return offset; + } + } + + // read from the pipe now + bool done; + int ret; + if (d->consoleMode) { + // read a fraction of the number of characters as requested, + // to guarantee the result fits + int num = size / CONSOLE_CHAREXPAND; #ifdef QPIPE_SECURE - SecureArray destbuf(num * sizeof(ushort), 0); + SecureArray destbuf(num * sizeof(ushort), 0); #else - QByteArray destbuf(num * sizeof(ushort), 0); -#endif - ushort *dest = (ushort *)destbuf.data(); - - ret = pipe_read_console(d->pipe, dest, num, &done, d->dec); - if(ret != -1) - { - // for security, encode one character at a time without - // performing a QString conversion of the whole thing - QTextCodec *codec = QTextCodec::codecForMib(106); - QTextCodec::ConverterState cstate(QTextCodec::IgnoreHeader); - int at = 0; - for(int n = 0; n < ret; ++n) - { - QChar c(dest[n]); - QByteArray out = codec->fromUnicode(&c, 1, &cstate); - memcpy(data + offset + at, out.data(), out.size()); - at += out.size(); - } - ret = at; // change ret to actual bytes - } - } - else - ret = pipe_read(d->pipe, data + offset, size, &done); - if(done || ret == -1) // eof or error - { - // did we already have some data? if so, defer the eof/error - if(offset) - { - d->forceNotify = true; - if(done) - d->atEnd = true; - else - d->atError = true; - - // readTimer is a singleshot, so we have to start it - // for forceNotify to work - d->readTimer->start(); - } - // otherwise, bail - else - { - close(); - if(done) - return 0; - else - return -1; - } - } - else - offset += ret; - - // pipe still active? resume the pipeReader - if(wasBlocked && !d->atEnd && !d->atError) - d->pipeReader->resume(); - - // no data means error - if(offset == 0) - return -1; - - return offset; + QByteArray destbuf(num * sizeof(ushort), 0); +#endif + ushort *dest = (ushort *)destbuf.data(); + + ret = pipe_read_console(d->pipe, dest, num, &done, d->dec); + if (ret != -1) { + // for security, encode one character at a time without + // performing a QString conversion of the whole thing + QTextCodec *codec = QTextCodec::codecForMib(106); + QTextCodec::ConverterState cstate(QTextCodec::IgnoreHeader); + int at = 0; + for (int n = 0; n < ret; ++n) { + QChar c(dest[n]); + QByteArray out = codec->fromUnicode(&c, 1, &cstate); + memcpy(data + offset + at, out.data(), out.size()); + at += out.size(); + } + ret = at; // change ret to actual bytes + } + } else { + ret = pipe_read(d->pipe, data + offset, size, &done); + } + if (done || ret == -1) { // eof or error + // did we already have some data? if so, defer the eof/error + if (offset) { + d->forceNotify = true; + if (done) { + d->atEnd = true; + } else { + d->atError = true; + } + + // readTimer is a singleshot, so we have to start it + // for forceNotify to work + d->readTimer->start(); + } + // otherwise, bail + else { + close(); + if (done) { + return 0; + } else { + return -1; + } + } + } else { + offset += ret; + } + + // pipe still active? resume the pipeReader + if (wasBlocked && !d->atEnd && !d->atError) { + d->pipeReader->resume(); + } + + // no data means error + if (offset == 0) { + return -1; + } + + return offset; #endif #ifdef Q_OS_UNIX - bool done; - int r = pipe_read(d->pipe, data, maxsize, &done); - if(done) - { - close(); - return 0; - } - if(r == -1) - { - close(); - return -1; - } - - // no data means error - if(r == 0) - return -1; - - return r; + bool done; + int r = pipe_read(d->pipe, data, maxsize, &done); + if (done) { + close(); + return 0; + } + if (r == -1) { + close(); + return -1; + } + + // no data means error + if (r == 0) { + return -1; + } + + return r; #endif } int QPipeDevice::write(const char *data, int size) { - if(d->type != QPipeDevice::Write) - return -1; + if (d->type != QPipeDevice::Write) { + return -1; + } - // allowed to write? - if(!d->canWrite) - return -1; + // allowed to write? + if (!d->canWrite) { + return -1; + } - // if size is zero, don't bother - if(size == 0) - return 0; + // if size is zero, don't bother + if (size == 0) { + return 0; + } - int r; + int r; #ifdef Q_OS_WIN - if(!d->pipeWriter) - { + if (!d->pipeWriter) { #ifdef USE_POLL - d->pipeWriter = new QPipeWriterPoll(d->pipe, d); + d->pipeWriter = new QPipeWriterPoll(d->pipe, d); #else - // console always polls, no matter what - if(d->consoleMode) - d->pipeWriter = new QPipeReaderPoll(d->pipe, d); - else - d->pipeWriter = new QPipeWriterThread(d->pipe, d); -#endif - connect(d->pipeWriter, SIGNAL(canWrite(int, int)), d, SLOT(pw_canWrite(int, int))); - d->pipeWriter->start(); - } - - if(d->consoleMode) - { - // Note: we convert to QString here, but it should not be a - // security issue (see pipe_write_console comment above) - - // for console, just write direct. we won't use pipewriter - QString out = QString::fromUtf8(QByteArray(data, size)); - r = pipe_write_console(d->pipe, out.utf16(), out.length()); - if(r == -1) - return -1; - - // convert characters to bytes - r = out.mid(0, r).toUtf8().size(); - - // simulate. we invoke the signal of pipewriter rather than our - // own slot, so that the invoke can be cancelled. - d->canWrite = false; - QMetaObject::invokeMethod(d->pipeWriter, "canWrite", Qt::QueuedConnection, Q_ARG(int, 0), Q_ARG(int, r)); - } - else - { - d->canWrite = false; - r = d->pipeWriter->write(data, size); - } - - d->lastTaken = r; - if(r == -1) - { - close(); - return -1; - } + // console always polls, no matter what + if (d->consoleMode) { + d->pipeWriter = new QPipeReaderPoll(d->pipe, d); + } else { + d->pipeWriter = new QPipeWriterThread(d->pipe, d); + } +#endif + connect(d->pipeWriter, SIGNAL(canWrite(int,int)), d, SLOT(pw_canWrite(int,int))); + d->pipeWriter->start(); + } + + if (d->consoleMode) { + // Note: we convert to QString here, but it should not be a + // security issue (see pipe_write_console comment above) + + // for console, just write direct. we won't use pipewriter + QString out = QString::fromUtf8(QByteArray(data, size)); + r = pipe_write_console(d->pipe, out.utf16(), out.length()); + if (r == -1) { + return -1; + } + + // convert characters to bytes + r = out.mid(0, r).toUtf8().size(); + + // simulate. we invoke the signal of pipewriter rather than our + // own slot, so that the invoke can be cancelled. + d->canWrite = false; + QMetaObject::invokeMethod(d->pipeWriter, "canWrite", Qt::QueuedConnection, Q_ARG(int, 0), Q_ARG(int, r)); + } else { + d->canWrite = false; + r = d->pipeWriter->write(data, size); + } + + d->lastTaken = r; + if (r == -1) { + close(); + return -1; + } #endif #ifdef Q_OS_UNIX - r = pipe_write(d->pipe, data, size); - d->lastTaken = r; - if(r == -1) - { - close(); - return -1; - } - - d->canWrite = false; - d->sn_write->setEnabled(true); -#endif - return r; + r = pipe_write(d->pipe, data, size); + d->lastTaken = r; + if (r == -1) { + close(); + return -1; + } + + d->canWrite = false; + d->sn_write->setEnabled(true); +#endif + return r; } int QPipeDevice::writeResult(int *written) const { - if(written) - *written = d->lastWritten; - return d->writeResult; + if (written) { + *written = d->lastWritten; + } + return d->writeResult; } //---------------------------------------------------------------------------- // QPipeEnd //---------------------------------------------------------------------------- -enum ResetMode -{ - ResetSession = 0, - ResetSessionAndData = 1, - ResetAll = 2 +enum ResetMode { + ResetSession = 0, + ResetSessionAndData = 1, + ResetAll = 2 }; class QPipeEnd::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - QPipeEnd *q; - QPipeDevice pipe; - QPipeDevice::Type type; - QByteArray buf; - QByteArray curWrite; + QPipeEnd *q; + QPipeDevice pipe; + QPipeDevice::Type type; + QByteArray buf; + QByteArray curWrite; #ifdef Q_OS_WIN - bool consoleMode; + bool consoleMode; #endif #ifdef QPIPE_SECURE - bool secure; - SecureArray sec_buf; - SecureArray sec_curWrite; -#endif - SafeTimer readTrigger, writeTrigger, closeTrigger, writeErrorTrigger; - bool canRead, activeWrite; - int lastWrite; - bool closeLater; - bool closing; - - Private(QPipeEnd *_q) : QObject(_q), q(_q), pipe(this), readTrigger(this), writeTrigger(this), closeTrigger(this), writeErrorTrigger(this) - { - readTrigger.setSingleShot(true); - writeTrigger.setSingleShot(true); - closeTrigger.setSingleShot(true); - writeErrorTrigger.setSingleShot(true); - connect(&pipe, SIGNAL(notify()), SLOT(pipe_notify())); - connect(&readTrigger, SIGNAL(timeout()), SLOT(doRead())); - connect(&writeTrigger, SIGNAL(timeout()), SLOT(doWrite())); - connect(&closeTrigger, SIGNAL(timeout()), SLOT(doClose())); - connect(&writeErrorTrigger, SIGNAL(timeout()), SLOT(doWriteError())); - reset(ResetSessionAndData); - } - - void reset(ResetMode mode) - { - pipe.close(); - readTrigger.stop(); - writeTrigger.stop(); - closeTrigger.stop(); - writeErrorTrigger.stop(); - canRead = false; - activeWrite = false; - lastWrite = 0; - closeLater = false; - closing = false; - curWrite.clear(); + bool secure; + SecureArray sec_buf; + SecureArray sec_curWrite; +#endif + SafeTimer readTrigger, writeTrigger, closeTrigger, writeErrorTrigger; + bool canRead, activeWrite; + int lastWrite; + bool closeLater; + bool closing; + + Private(QPipeEnd *_q) : QObject(_q), q(_q), pipe(this), readTrigger(this), writeTrigger(this), closeTrigger(this), writeErrorTrigger(this) + { + readTrigger.setSingleShot(true); + writeTrigger.setSingleShot(true); + closeTrigger.setSingleShot(true); + writeErrorTrigger.setSingleShot(true); + connect(&pipe, SIGNAL(notify()), SLOT(pipe_notify())); + connect(&readTrigger, SIGNAL(timeout()), SLOT(doRead())); + connect(&writeTrigger, SIGNAL(timeout()), SLOT(doWrite())); + connect(&closeTrigger, SIGNAL(timeout()), SLOT(doClose())); + connect(&writeErrorTrigger, SIGNAL(timeout()), SLOT(doWriteError())); + reset(ResetSessionAndData); + } + + void reset(ResetMode mode) + { + pipe.close(); + readTrigger.stop(); + writeTrigger.stop(); + closeTrigger.stop(); + writeErrorTrigger.stop(); + canRead = false; + activeWrite = false; + lastWrite = 0; + closeLater = false; + closing = false; + curWrite.clear(); #ifdef QPIPE_SECURE - secure = false; - sec_curWrite.clear(); + secure = false; + sec_curWrite.clear(); #endif - if(mode >= ResetSessionAndData) - { - buf.clear(); + if (mode >= ResetSessionAndData) { + buf.clear(); #ifdef QPIPE_SECURE - sec_buf.clear(); + sec_buf.clear(); #endif - } - } + } + } - void setup(Q_PIPE_ID id, QPipeDevice::Type _type) - { - type = _type; + void setup(Q_PIPE_ID id, QPipeDevice::Type _type) + { + type = _type; #ifdef Q_OS_WIN - consoleMode = pipe_is_a_console(id); + consoleMode = pipe_is_a_console(id); #endif - pipe.take(id, type); - } + pipe.take(id, type); + } - int pendingSize() const - { + int pendingSize() const + { #ifdef QPIPE_SECURE - if(secure) - return sec_buf.size(); - else + if (secure) { + return sec_buf.size(); + } else #endif - return buf.size(); - } + return buf.size(); + } - int pendingFreeSize() const - { + int pendingFreeSize() const + { #ifdef QPIPE_SECURE - if(secure) - return qMax(PIPEEND_READBUF_SEC - sec_buf.size(), 0); - else + if (secure) { + return qMax(PIPEEND_READBUF_SEC - sec_buf.size(), 0); + } else #endif - return qMax(PIPEEND_READBUF - buf.size(), 0); - } + return qMax(PIPEEND_READBUF - buf.size(), 0); + } - void appendArray(QByteArray *a, const QByteArray &b) - { - (*a) += b; - } + void appendArray(QByteArray *a, const QByteArray &b) + { + (*a) += b; + } #ifdef QPIPE_SECURE - void appendArray(SecureArray *a, const SecureArray &b) - { - a->append(b); - } + void appendArray(SecureArray *a, const SecureArray &b) + { + a->append(b); + } #endif - void takeArray(QByteArray *a, int len) - { - char *p = a->data(); - int newsize = a->size() - len; - memmove(p, p + len, newsize); - a->resize(newsize); - } + void takeArray(QByteArray *a, int len) + { + char *p = a->data(); + int newsize = a->size() - len; + memmove(p, p + len, newsize); + a->resize(newsize); + } #ifdef QPIPE_SECURE - void takeArray(SecureArray *a, int len) - { - char *p = a->data(); - int newsize = a->size() - len; - memmove(p, p + len, newsize); - a->resize(newsize); - } -#endif - - void setupNextRead() - { - if(pipe.isValid() && canRead) - { - canRead = false; - readTrigger.start(0); - } - } - - void setupNextWrite() - { - if(!activeWrite) - { - activeWrite = true; - writeTrigger.start(0); - } - } - - QByteArray read(QByteArray *buf, int bytes) - { - QByteArray a; - if(bytes == -1 || bytes > buf->size()) - { - a = *buf; - } - else - { - a.resize(bytes); - memcpy(a.data(), buf->data(), a.size()); - } - - takeArray(buf, a.size()); - setupNextRead(); - return a; - } - - void write(QByteArray *buf, const QByteArray &a) - { - appendArray(buf, a); - setupNextWrite(); - } + void takeArray(SecureArray *a, int len) + { + char *p = a->data(); + int newsize = a->size() - len; + memmove(p, p + len, newsize); + a->resize(newsize); + } +#endif + + void setupNextRead() + { + if (pipe.isValid() && canRead) { + canRead = false; + readTrigger.start(0); + } + } + + void setupNextWrite() + { + if (!activeWrite) { + activeWrite = true; + writeTrigger.start(0); + } + } + + QByteArray read(QByteArray *buf, int bytes) + { + QByteArray a; + if (bytes == -1 || bytes > buf->size()) { + a = *buf; + } else { + a.resize(bytes); + memcpy(a.data(), buf->data(), a.size()); + } + + takeArray(buf, a.size()); + setupNextRead(); + return a; + } + + void write(QByteArray *buf, const QByteArray &a) + { + appendArray(buf, a); + setupNextWrite(); + } #ifdef QPIPE_SECURE - SecureArray readSecure(SecureArray *buf, int bytes) - { - SecureArray a; - if(bytes == -1 || bytes > buf->size()) - { - a = *buf; - } - else - { - a.resize(bytes); - memcpy(a.data(), buf->data(), a.size()); - } - - takeArray(buf, a.size()); - setupNextRead(); - return a; - } - - void writeSecure(SecureArray *buf, const SecureArray &a) - { - appendArray(buf, a); - setupNextWrite(); - } + SecureArray readSecure(SecureArray *buf, int bytes) + { + SecureArray a; + if (bytes == -1 || bytes > buf->size()) { + a = *buf; + } else { + a.resize(bytes); + memcpy(a.data(), buf->data(), a.size()); + } + + takeArray(buf, a.size()); + setupNextRead(); + return a; + } + + void writeSecure(SecureArray *buf, const SecureArray &a) + { + appendArray(buf, a); + setupNextWrite(); + } #endif public slots: - void pipe_notify() - { - if(pipe.type() == QPipeDevice::Read) - { - doRead(); - } - else - { - int x; - int writeResult = pipe.writeResult(&x); - if(writeResult == -1) - lastWrite = x; // if error, we may have written less bytes - - // remove what we just wrote - bool moreData = false; + void pipe_notify() + { + if (pipe.type() == QPipeDevice::Read) { + doRead(); + } else { + int x; + int writeResult = pipe.writeResult(&x); + if (writeResult == -1) { + lastWrite = x; // if error, we may have written less bytes + } + + // remove what we just wrote + bool moreData = false; #ifdef QPIPE_SECURE - if(secure) - { - takeArray(&sec_buf, lastWrite); - moreData = !sec_buf.isEmpty(); - } - else -#endif - { - takeArray(&buf, lastWrite); - moreData = !buf.isEmpty(); - } + if (secure) { + takeArray(&sec_buf, lastWrite); + moreData = !sec_buf.isEmpty(); + } else +#endif + { + takeArray(&buf, lastWrite); + moreData = !buf.isEmpty(); + } #ifdef QPIPE_SECURE - sec_curWrite.clear(); -#endif - curWrite.clear(); - - x = lastWrite; - lastWrite = 0; - - if(writeResult == 0) - { - // more to write? do it - if(moreData) - { - writeTrigger.start(0); - } - // done with all writing - else - { - activeWrite = false; - if(closeLater) - { - closeLater = false; - closeTrigger.start(0); - } - } - } - else - writeErrorTrigger.start(); - - if(x > 0) - emit q->bytesWritten(x); - } - } - - void doRead() - { - doReadActual(true); - } - - void doReadActual(bool sigs) - { - int left = pendingFreeSize(); - if(left == 0) - { - canRead = true; - return; - } - - int max; + sec_curWrite.clear(); +#endif + curWrite.clear(); + + x = lastWrite; + lastWrite = 0; + + if (writeResult == 0) { + // more to write? do it + if (moreData) { + writeTrigger.start(0); + } + // done with all writing + else { + activeWrite = false; + if (closeLater) { + closeLater = false; + closeTrigger.start(0); + } + } + } else { + writeErrorTrigger.start(); + } + + if (x > 0) { + emit q->bytesWritten(x); + } + } + } + + void doRead() + { + doReadActual(true); + } + + void doReadActual(bool sigs) + { + int left = pendingFreeSize(); + if (left == 0) { + canRead = true; + return; + } + + int max; #ifdef Q_OS_WIN - if(consoleMode) - { - // need a minimum amount for console - if(left < CONSOLE_CHAREXPAND) - { - canRead = true; - return; - } - - // don't use pipe.bytesAvailable() for console mode, - // as it is somewhat bogus. fortunately, there is - // no problem with overreading from the console. - max = qMin(left, 32); - } - else -#endif - { - max = qMin(left, pipe.bytesAvailable()); - } - - int ret; + if (consoleMode) { + // need a minimum amount for console + if (left < CONSOLE_CHAREXPAND) { + canRead = true; + return; + } + + // don't use pipe.bytesAvailable() for console mode, + // as it is somewhat bogus. fortunately, there is + // no problem with overreading from the console. + max = qMin(left, 32); + } else +#endif + { + max = qMin(left, pipe.bytesAvailable()); + } + + int ret; #ifdef QPIPE_SECURE - if(secure) - { - SecureArray a(max); - ret = pipe.read(a.data(), a.size()); - if(ret >= 1) - { - a.resize(ret); - sec_buf.append(a); - } - } - else -#endif - { - QByteArray a(max, 0); - ret = pipe.read(a.data(), a.size()); - if(ret >= 1) - { - a.resize(ret); - buf += a; - } - } - - if(ret < 1) - { - reset(ResetSession); - if(sigs) - { - if(ret == 0) - emit q->error(QPipeEnd::ErrorEOF); - else - emit q->error(QPipeEnd::ErrorBroken); - } - return; - } - - if(sigs) - emit q->readyRead(); - } - - void doWrite() - { - int ret; + if (secure) { + SecureArray a(max); + ret = pipe.read(a.data(), a.size()); + if (ret >= 1) { + a.resize(ret); + sec_buf.append(a); + } + } else +#endif + { + QByteArray a(max, 0); + ret = pipe.read(a.data(), a.size()); + if (ret >= 1) { + a.resize(ret); + buf += a; + } + } + + if (ret < 1) { + reset(ResetSession); + if (sigs) { + if (ret == 0) { + emit q->error(QPipeEnd::ErrorEOF); + } else { + emit q->error(QPipeEnd::ErrorBroken); + } + } + return; + } + + if (sigs) { + emit q->readyRead(); + } + } + + void doWrite() + { + int ret; #ifdef QPIPE_SECURE - if(secure) - { - sec_curWrite.resize(qMin(PIPEEND_BLOCK, sec_buf.size())); - memcpy(sec_curWrite.data(), sec_buf.data(), sec_curWrite.size()); - - ret = pipe.write(sec_curWrite.data(), sec_curWrite.size()); - } - else -#endif - { - curWrite.resize(qMin(PIPEEND_BLOCK, buf.size())); - memcpy(curWrite.data(), buf.data(), curWrite.size()); - - ret = pipe.write(curWrite.data(), curWrite.size()); - } - - if(ret == -1) - { - reset(ResetSession); - emit q->error(QPipeEnd::ErrorBroken); - return; - } - - lastWrite = ret; - } - - void doClose() - { - reset(ResetSession); - emit q->closed(); - } - - void doWriteError() - { - reset(ResetSession); - emit q->error(QPipeEnd::ErrorBroken); - } + if (secure) { + sec_curWrite.resize(qMin(PIPEEND_BLOCK, sec_buf.size())); + memcpy(sec_curWrite.data(), sec_buf.data(), sec_curWrite.size()); + + ret = pipe.write(sec_curWrite.data(), sec_curWrite.size()); + } else +#endif + { + curWrite.resize(qMin(PIPEEND_BLOCK, buf.size())); + memcpy(curWrite.data(), buf.data(), curWrite.size()); + + ret = pipe.write(curWrite.data(), curWrite.size()); + } + + if (ret == -1) { + reset(ResetSession); + emit q->error(QPipeEnd::ErrorBroken); + return; + } + + lastWrite = ret; + } + + void doClose() + { + reset(ResetSession); + emit q->closed(); + } + + void doWriteError() + { + reset(ResetSession); + emit q->error(QPipeEnd::ErrorBroken); + } }; QPipeEnd::QPipeEnd(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(this); + d = new Private(this); } QPipeEnd::~QPipeEnd() { - delete d; + delete d; } void QPipeEnd::reset() { - d->reset(ResetAll); + d->reset(ResetAll); } QPipeDevice::Type QPipeEnd::type() const { - return d->pipe.type(); + return d->pipe.type(); } bool QPipeEnd::isValid() const { - return d->pipe.isValid(); + return d->pipe.isValid(); } Q_PIPE_ID QPipeEnd::id() const { - return d->pipe.id(); + return d->pipe.id(); } int QPipeEnd::idAsInt() const { - return d->pipe.idAsInt(); + return d->pipe.idAsInt(); } void QPipeEnd::take(Q_PIPE_ID id, QPipeDevice::Type t) { - reset(); - d->setup(id, t); + reset(); + d->setup(id, t); } #ifdef QPIPE_SECURE void QPipeEnd::setSecurityEnabled(bool secure) { - // no change - if(d->secure == secure) - return; - - if(secure) - { - d->sec_buf = d->buf; - d->buf.clear(); - } - else - { - d->buf = d->sec_buf.toByteArray(); - d->sec_buf.clear(); - } - - d->secure = secure; + // no change + if (d->secure == secure) { + return; + } + + if (secure) { + d->sec_buf = d->buf; + d->buf.clear(); + } else { + d->buf = d->sec_buf.toByteArray(); + d->sec_buf.clear(); + } + + d->secure = secure; } #endif void QPipeEnd::enable() { - d->pipe.enable(); + d->pipe.enable(); } void QPipeEnd::close() { - if(!isValid() || d->closing) - return; + if (!isValid() || d->closing) { + return; + } - d->closing = true; + d->closing = true; - if(d->activeWrite) - d->closeLater = true; - else - d->closeTrigger.start(0); + if (d->activeWrite) { + d->closeLater = true; + } else { + d->closeTrigger.start(0); + } } void QPipeEnd::release() { - if(!isValid()) - return; + if (!isValid()) { + return; + } - d->pipe.release(); - d->reset(ResetSession); + d->pipe.release(); + d->reset(ResetSession); } bool QPipeEnd::setInheritable(bool enabled) { - return d->pipe.setInheritable(enabled); + return d->pipe.setInheritable(enabled); } void QPipeEnd::finalize() { - if(!isValid()) - return; + if (!isValid()) { + return; + } - if(d->pipe.bytesAvailable()) - d->doReadActual(false); - d->reset(ResetSession); + if (d->pipe.bytesAvailable()) { + d->doReadActual(false); + } + d->reset(ResetSession); } void QPipeEnd::finalizeAndRelease() { - if(!isValid()) - return; + if (!isValid()) { + return; + } - if(d->pipe.bytesAvailable()) - d->doReadActual(false); - d->pipe.release(); - d->reset(ResetSession); + if (d->pipe.bytesAvailable()) { + d->doReadActual(false); + } + d->pipe.release(); + d->reset(ResetSession); } int QPipeEnd::bytesAvailable() const { - return d->pendingSize(); + return d->pendingSize(); } int QPipeEnd::bytesToWrite() const { - return d->pendingSize(); + return d->pendingSize(); } QByteArray QPipeEnd::read(int bytes) { - return d->read(&d->buf, bytes); + return d->read(&d->buf, bytes); } void QPipeEnd::write(const QByteArray &buf) { - if(!isValid() || d->closing) - return; + if (!isValid() || d->closing) { + return; + } - if(buf.isEmpty()) - return; + if (buf.isEmpty()) { + return; + } #ifdef QPIPE_SECURE - if(d->secure) // call writeSecure() instead - return; + if (d->secure) { // call writeSecure() instead + return; + } #endif - d->write(&d->buf, buf); + d->write(&d->buf, buf); } #ifdef QPIPE_SECURE SecureArray QPipeEnd::readSecure(int bytes) { - return d->readSecure(&d->sec_buf, bytes); + return d->readSecure(&d->sec_buf, bytes); } void QPipeEnd::writeSecure(const SecureArray &buf) { - if(!isValid() || d->closing) - return; + if (!isValid() || d->closing) { + return; + } - if(buf.isEmpty()) - return; + if (buf.isEmpty()) { + return; + } - if(!d->secure) // call write() instead - return; + if (!d->secure) { // call write() instead + return; + } - d->writeSecure(&d->sec_buf, buf); + d->writeSecure(&d->sec_buf, buf); } #endif QByteArray QPipeEnd::takeBytesToWrite() { - // only call this on inactive sessions - if(isValid()) - return QByteArray(); + // only call this on inactive sessions + if (isValid()) { + return QByteArray(); + } - QByteArray a = d->buf; - d->buf.clear(); - return a; + QByteArray a = d->buf; + d->buf.clear(); + return a; } #ifdef QPIPE_SECURE SecureArray QPipeEnd::takeBytesToWriteSecure() { - // only call this on inactive sessions - if(isValid()) - return SecureArray(); + // only call this on inactive sessions + if (isValid()) { + return SecureArray(); + } - SecureArray a = d->sec_buf; - d->sec_buf.clear(); - return a; + SecureArray a = d->sec_buf; + d->sec_buf.clear(); + return a; } #endif //---------------------------------------------------------------------------- // QPipe //---------------------------------------------------------------------------- QPipe::QPipe(QObject *parent) -:i(parent), o(parent) + : i(parent), o(parent) { } @@ -2121,52 +2111,53 @@ void QPipe::reset() { - i.reset(); - o.reset(); + i.reset(); + o.reset(); } #ifdef QPIPE_SECURE bool QPipe::create(bool secure) #else bool QPipe::create() #endif { - reset(); + reset(); #ifdef Q_OS_WIN - SECURITY_ATTRIBUTES secAttr; - memset(&secAttr, 0, sizeof secAttr); - secAttr.nLength = sizeof secAttr; - secAttr.bInheritHandle = false; + SECURITY_ATTRIBUTES secAttr; + memset(&secAttr, 0, sizeof secAttr); + secAttr.nLength = sizeof secAttr; + secAttr.bInheritHandle = false; - HANDLE r, w; - if(!CreatePipe(&r, &w, &secAttr, 0)) - return false; - i.take(r, QPipeDevice::Read); - o.take(w, QPipeDevice::Write); + HANDLE r, w; + if (!CreatePipe(&r, &w, &secAttr, 0)) { + return false; + } + i.take(r, QPipeDevice::Read); + o.take(w, QPipeDevice::Write); #endif #ifdef Q_OS_UNIX - int p[2]; - if(pipe(p) == -1) - return false; - if(!pipe_set_inheritable(p[0], false, 0) || - !pipe_set_inheritable(p[1], false, 0)) - { - close(p[0]); - close(p[1]); - return false; - } - i.take(p[0], QPipeDevice::Read); - o.take(p[1], QPipeDevice::Write); + int p[2]; + if (pipe(p) == -1) { + return false; + } + if (!pipe_set_inheritable(p[0], false, 0) || + !pipe_set_inheritable(p[1], false, 0)) { + close(p[0]); + close(p[1]); + return false; + } + i.take(p[0], QPipeDevice::Read); + o.take(p[1], QPipeDevice::Write); #endif #ifdef QPIPE_SECURE - i.setSecurityEnabled(secure); - o.setSecurityEnabled(secure); + i.setSecurityEnabled(secure); + o.setSecurityEnabled(secure); #endif - return true; + return true; } } diff --git a/src/support/synchronizer.cpp b/src/support/synchronizer.cpp --- a/src/support/synchronizer.cpp +++ b/src/support/synchronizer.cpp @@ -35,498 +35,490 @@ #include #endif -namespace QCA { +namespace QCA +{ //---------------------------------------------------------------------------- // TimerFixer //---------------------------------------------------------------------------- class TimerFixer : public QObject { - Q_OBJECT + Q_OBJECT public: - struct TimerInfo - { - int id; - int interval; - QTime time; - bool fixInterval; + struct TimerInfo { + int id; + int interval; + QTime time; + bool fixInterval; - TimerInfo() : fixInterval(false) {} - }; + TimerInfo() : fixInterval(false) {} + }; - TimerFixer *fixerParent; - QList fixerChildren; + TimerFixer *fixerParent; + QList fixerChildren; - QObject *target; - QAbstractEventDispatcher *ed; - QList timers; + QObject *target; + QAbstractEventDispatcher *ed; + QList timers; - static bool haveFixer(QObject *obj) - { - return obj->findChild() ? true : false; - } + static bool haveFixer(QObject *obj) + { + return obj->findChild() ? true : false; + } - TimerFixer(QObject *_target, TimerFixer *_fp = 0) : QObject(_target) - { - ed = 0; + TimerFixer(QObject *_target, TimerFixer *_fp = 0) : QObject(_target) + { + ed = 0; - target = _target; - fixerParent = _fp; - if(fixerParent) - fixerParent->fixerChildren.append(this); + target = _target; + fixerParent = _fp; + if (fixerParent) { + fixerParent->fixerChildren.append(this); + } #ifdef TIMERFIXER_DEBUG - printf("TimerFixer[%p] pairing with %p (%s)\n", this, target, target->metaObject()->className()); + printf("TimerFixer[%p] pairing with %p (%s)\n", this, target, target->metaObject()->className()); #endif - edlink(); - target->installEventFilter(this); - - QObjectList list = target->children(); - for(int n = 0; n < list.count(); ++n) - hook(list[n]); - } - - ~TimerFixer() - { - if(fixerParent) - fixerParent->fixerChildren.removeAll(this); - - QList list = fixerChildren; - for(int n = 0; n < list.count(); ++n) - delete list[n]; - list.clear(); - - updateTimerList(); // do this just to trip debug output - - target->removeEventFilter(this); - edunlink(); + edlink(); + target->installEventFilter(this); + + QObjectList list = target->children(); + for (int n = 0; n < list.count(); ++n) { + hook(list[n]); + } + } + + ~TimerFixer() + { + if (fixerParent) { + fixerParent->fixerChildren.removeAll(this); + } + + QList list = fixerChildren; + for (int n = 0; n < list.count(); ++n) { + delete list[n]; + } + list.clear(); + + updateTimerList(); // do this just to trip debug output + + target->removeEventFilter(this); + edunlink(); #ifdef TIMERFIXER_DEBUG - printf("TimerFixer[%p] unpaired with %p (%s)\n", this, target, target->metaObject()->className()); + printf("TimerFixer[%p] unpaired with %p (%s)\n", this, target, target->metaObject()->className()); #endif - } - - virtual bool event(QEvent *e) - { - switch(e->type()) - { - case QEvent::ThreadChange: // this happens second - //printf("TimerFixer[%p] self changing threads\n", this); - edunlink(); - QMetaObject::invokeMethod(this, "fixTimers", Qt::QueuedConnection); - break; - default: - break; - } - - return QObject::event(e); - } - - virtual bool eventFilter(QObject *, QEvent *e) - { - switch(e->type()) - { - case QEvent::ChildAdded: - hook(((QChildEvent *)e)->child()); - break; - case QEvent::ChildRemoved: - unhook(((QChildEvent *)e)->child()); - break; - case QEvent::Timer: - handleTimerEvent(((QTimerEvent *)e)->timerId()); - break; - case QEvent::ThreadChange: // this happens first + } + + virtual bool event(QEvent *e) + { + switch (e->type()) { + case QEvent::ThreadChange: // this happens second + //printf("TimerFixer[%p] self changing threads\n", this); + edunlink(); + QMetaObject::invokeMethod(this, "fixTimers", Qt::QueuedConnection); + break; + default: + break; + } + + return QObject::event(e); + } + + virtual bool eventFilter(QObject *, QEvent *e) + { + switch (e->type()) { + case QEvent::ChildAdded: + hook(((QChildEvent *)e)->child()); + break; + case QEvent::ChildRemoved: + unhook(((QChildEvent *)e)->child()); + break; + case QEvent::Timer: + handleTimerEvent(((QTimerEvent *)e)->timerId()); + break; + case QEvent::ThreadChange: // this happens first #ifdef TIMERFIXER_DEBUG - printf("TimerFixer[%p] target changing threads\n", this); + printf("TimerFixer[%p] target changing threads\n", this); #endif - break; - default: - break; - } + break; + default: + break; + } - return false; - } + return false; + } private slots: - void edlink() - { - ed = QAbstractEventDispatcher::instance(); - //printf("TimerFixer[%p] linking to dispatcher %p\n", this, ed); - connect(ed, SIGNAL(aboutToBlock()), SLOT(ed_aboutToBlock())); - } - - void edunlink() - { - //printf("TimerFixer[%p] unlinking from dispatcher %p\n", this, ed); - if(ed) - { - disconnect(ed, SIGNAL(aboutToBlock()), this, SLOT(ed_aboutToBlock())); - ed = 0; - } - } - - void ed_aboutToBlock() - { - //printf("TimerFixer[%p] aboutToBlock\n", this); - updateTimerList(); - } - - void fixTimers() - { - updateTimerList(); - edlink(); - - for(int n = 0; n < timers.count(); ++n) - { - TimerInfo &info = timers[n]; - - QThread *objectThread = target->thread(); - QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance(objectThread); - - int timeLeft = qMax(info.interval - info.time.elapsed(), 0); - info.fixInterval = true; - ed->unregisterTimer(info.id); + void edlink() + { + ed = QAbstractEventDispatcher::instance(); + //printf("TimerFixer[%p] linking to dispatcher %p\n", this, ed); + connect(ed, SIGNAL(aboutToBlock()), SLOT(ed_aboutToBlock())); + } + + void edunlink() + { + //printf("TimerFixer[%p] unlinking from dispatcher %p\n", this, ed); + if (ed) { + disconnect(ed, SIGNAL(aboutToBlock()), this, SLOT(ed_aboutToBlock())); + ed = 0; + } + } + + void ed_aboutToBlock() + { + //printf("TimerFixer[%p] aboutToBlock\n", this); + updateTimerList(); + } + + void fixTimers() + { + updateTimerList(); + edlink(); + + for (int n = 0; n < timers.count(); ++n) { + TimerInfo &info = timers[n]; + + QThread *objectThread = target->thread(); + QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance(objectThread); + + int timeLeft = qMax(info.interval - info.time.elapsed(), 0); + info.fixInterval = true; + ed->unregisterTimer(info.id); #if QT_VERSION >= 0x050000 - info.id = ed->registerTimer(timeLeft, Qt::CoarseTimer, target); + info.id = ed->registerTimer(timeLeft, Qt::CoarseTimer, target); #else - info.id = ed->registerTimer(timeLeft, target); + info.id = ed->registerTimer(timeLeft, target); #endif #ifdef TIMERFIXER_DEBUG - printf("TimerFixer[%p] adjusting [%d] to %d\n", this, info.id, timeLeft); + printf("TimerFixer[%p] adjusting [%d] to %d\n", this, info.id, timeLeft); #endif - } - } + } + } private: - void hook(QObject *obj) - { - // don't watch a fixer or any object that already has one - // SafeTimer has own method to fix timers, skip it too - if(obj == this || qobject_cast(obj) || haveFixer(obj) || qobject_cast(obj)) - return; - - new TimerFixer(obj, this); - } - - void unhook(QObject *obj) - { - TimerFixer *t = 0; - for(int n = 0; n < fixerChildren.count(); ++n) - { - if(fixerChildren[n]->target == obj) - t = fixerChildren[n]; - } - delete t; - } - - void handleTimerEvent(int id) - { - bool found = false; - int n; - for(n = 0; n < timers.count(); ++n) - { - if(timers[n].id == id) - { - found = true; - break; - } - } - if(!found) - { - //printf("*** unrecognized timer [%d] activated ***\n", id); - return; - } - - TimerInfo &info = timers[n]; + void hook(QObject *obj) + { + // don't watch a fixer or any object that already has one + // SafeTimer has own method to fix timers, skip it too + if (obj == this || qobject_cast(obj) || haveFixer(obj) || qobject_cast(obj)) { + return; + } + + new TimerFixer(obj, this); + } + + void unhook(QObject *obj) + { + TimerFixer *t = 0; + for (int n = 0; n < fixerChildren.count(); ++n) { + if (fixerChildren[n]->target == obj) { + t = fixerChildren[n]; + } + } + delete t; + } + + void handleTimerEvent(int id) + { + bool found = false; + int n; + for (n = 0; n < timers.count(); ++n) { + if (timers[n].id == id) { + found = true; + break; + } + } + if (!found) { + //printf("*** unrecognized timer [%d] activated ***\n", id); + return; + } + + TimerInfo &info = timers[n]; #ifdef TIMERFIXER_DEBUG - printf("TimerFixer[%p] timer [%d] activated!\n", this, info.id); + printf("TimerFixer[%p] timer [%d] activated!\n", this, info.id); #endif - if(info.fixInterval) - { + if (info.fixInterval) { #ifdef TIMERFIXER_DEBUG - printf("restoring correct interval (%d)\n", info.interval); + printf("restoring correct interval (%d)\n", info.interval); #endif - info.fixInterval = false; - ed->unregisterTimer(info.id); + info.fixInterval = false; + ed->unregisterTimer(info.id); #if QT_VERSION >= 0x050000 - info.id = ed->registerTimer(info.interval, Qt::CoarseTimer, target); + info.id = ed->registerTimer(info.interval, Qt::CoarseTimer, target); #else - info.id = ed->registerTimer(info.interval, target); + info.id = ed->registerTimer(info.interval, target); #endif - } - - info.time.start(); - } - - void updateTimerList() - { - QList edtimers; - if(ed) - edtimers = ed->registeredTimers(target); - - // removed? - for(int n = 0; n < timers.count(); ++n) - { - bool found = false; - int id = timers[n].id; - for(int i = 0; i < edtimers.count(); ++i) - { + } + + info.time.start(); + } + + void updateTimerList() + { + QList edtimers; + if (ed) { + edtimers = ed->registeredTimers(target); + } + + // removed? + for (int n = 0; n < timers.count(); ++n) { + bool found = false; + int id = timers[n].id; + for (int i = 0; i < edtimers.count(); ++i) { #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - if(edtimers[i].timerId == id) + if (edtimers[i].timerId == id) #else - if(edtimers[i].first == id) + if (edtimers[i].first == id) #endif - { - found = true; - break; - } - } - - if(!found) - { - timers.removeAt(n); - --n; + { + found = true; + break; + } + } + + if (!found) { + timers.removeAt(n); + --n; #ifdef TIMERFIXER_DEBUG - printf("TimerFixer[%p] timer [%d] removed\n", this, id); + printf("TimerFixer[%p] timer [%d] removed\n", this, id); #endif - } - } + } + } - // added? - for(int n = 0; n < edtimers.count(); ++n) - { + // added? + for (int n = 0; n < edtimers.count(); ++n) { #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - int id = edtimers[n].timerId; + int id = edtimers[n].timerId; #else - int id = edtimers[n].first; + int id = edtimers[n].first; #endif - bool found = false; - for(int i = 0; i < timers.count(); ++i) - { - if(timers[i].id == id) - { - found = true; - break; - } - } - - if(!found) - { - TimerInfo info; - info.id = id; + bool found = false; + for (int i = 0; i < timers.count(); ++i) { + if (timers[i].id == id) { + found = true; + break; + } + } + + if (!found) { + TimerInfo info; + info.id = id; #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - info.interval = edtimers[n].interval; + info.interval = edtimers[n].interval; #else - info.interval = edtimers[n].second; + info.interval = edtimers[n].second; #endif - info.time.start(); - timers += info; + info.time.start(); + timers += info; #ifdef TIMERFIXER_DEBUG - printf("TimerFixer[%p] timer [%d] added (interval=%d)\n", this, info.id, info.interval); + printf("TimerFixer[%p] timer [%d] added (interval=%d)\n", this, info.id, info.interval); #endif - } - } - } + } + } + } }; //---------------------------------------------------------------------------- // Synchronizer //---------------------------------------------------------------------------- class SynchronizerAgent : public QObject { - Q_OBJECT + Q_OBJECT public: - SynchronizerAgent(QObject *parent = 0) : QObject(parent) - { - QMetaObject::invokeMethod(this, "started", Qt::QueuedConnection); - } + SynchronizerAgent(QObject *parent = 0) : QObject(parent) + { + QMetaObject::invokeMethod(this, "started", Qt::QueuedConnection); + } signals: - void started(); + void started(); }; class Synchronizer::Private : public QThread { - Q_OBJECT + Q_OBJECT public: - Synchronizer *q; - - bool active; - bool do_quit; - bool cond_met; - - QObject *obj; - QEventLoop *loop; - SynchronizerAgent *agent; - TimerFixer *fixer; - QMutex m; - QWaitCondition w; - QThread *orig_thread; - - Private(QObject *_obj, Synchronizer *_q) - : QThread(_q) - , q(_q) - , active(false) - , do_quit(false) - , cond_met(false) - , obj(_obj) - , loop(0) - , agent(0) - , fixer(0) - , m(QMutex::NonRecursive) - , w() - , orig_thread(0) - { - // SafeTimer has own method to fix timers, skip it too - if (!qobject_cast(obj)) - fixer = new TimerFixer(obj); - } - - ~Private() - { - stop(); - delete fixer; - } - - void start() - { - if(active) - return; - - m.lock(); - active = true; - do_quit = false; - QThread::start(); - w.wait(&m); - m.unlock(); - } - - void stop() - { - if(!active) - return; - - m.lock(); - do_quit = true; - w.wakeOne(); - m.unlock(); - wait(); - active = false; - } - - bool waitForCondition(int msecs) - { - unsigned long time = ULONG_MAX; - if(msecs != -1) - time = msecs; - - // move object to the worker thread - cond_met = false; - orig_thread = QThread::currentThread(); - q->setParent(0); // don't follow the object - QObject *orig_parent = obj->parent(); - obj->setParent(0); // unparent the target or the move will fail - obj->moveToThread(this); - - // tell the worker thread to start, wait for completion - m.lock(); - w.wakeOne(); - if(!w.wait(&m, time)) - { - if(loop) - { - // if we timed out, tell the worker to quit - QMetaObject::invokeMethod(loop, "quit"); - w.wait(&m); - } - } - - // at this point the worker is done. cleanup and return - m.unlock(); - - // restore parents - obj->setParent(orig_parent); - q->setParent(obj); - - return cond_met; - } - - void conditionMet() - { - if(!loop) - return; - loop->quit(); - cond_met = true; - } + Synchronizer *q; + + bool active; + bool do_quit; + bool cond_met; + + QObject *obj; + QEventLoop *loop; + SynchronizerAgent *agent; + TimerFixer *fixer; + QMutex m; + QWaitCondition w; + QThread *orig_thread; + + Private(QObject *_obj, Synchronizer *_q) + : QThread(_q) + , q(_q) + , active(false) + , do_quit(false) + , cond_met(false) + , obj(_obj) + , loop(0) + , agent(0) + , fixer(0) + , m(QMutex::NonRecursive) + , w() + , orig_thread(0) + { + // SafeTimer has own method to fix timers, skip it too + if (!qobject_cast(obj)) { + fixer = new TimerFixer(obj); + } + } + + ~Private() + { + stop(); + delete fixer; + } + + void start() + { + if (active) { + return; + } + + m.lock(); + active = true; + do_quit = false; + QThread::start(); + w.wait(&m); + m.unlock(); + } + + void stop() + { + if (!active) { + return; + } + + m.lock(); + do_quit = true; + w.wakeOne(); + m.unlock(); + wait(); + active = false; + } + + bool waitForCondition(int msecs) + { + unsigned long time = ULONG_MAX; + if (msecs != -1) { + time = msecs; + } + + // move object to the worker thread + cond_met = false; + orig_thread = QThread::currentThread(); + q->setParent(0); // don't follow the object + QObject *orig_parent = obj->parent(); + obj->setParent(0); // unparent the target or the move will fail + obj->moveToThread(this); + + // tell the worker thread to start, wait for completion + m.lock(); + w.wakeOne(); + if (!w.wait(&m, time)) { + if (loop) { + // if we timed out, tell the worker to quit + QMetaObject::invokeMethod(loop, "quit"); + w.wait(&m); + } + } + + // at this point the worker is done. cleanup and return + m.unlock(); + + // restore parents + obj->setParent(orig_parent); + q->setParent(obj); + + return cond_met; + } + + void conditionMet() + { + if (!loop) { + return; + } + loop->quit(); + cond_met = true; + } protected: - virtual void run() - { - m.lock(); - QEventLoop eventLoop; - - while(1) - { - // thread now sleeps, waiting for work - w.wakeOne(); - w.wait(&m); - if(do_quit) - { - m.unlock(); - break; - } - - loop = &eventLoop; - agent = new SynchronizerAgent; - connect(agent, SIGNAL(started()), SLOT(agent_started()), Qt::DirectConnection); - - // run the event loop - eventLoop.exec(); - - delete agent; - agent = 0; - - // eventloop done, flush pending events - QCoreApplication::instance()->sendPostedEvents(); - QCoreApplication::instance()->sendPostedEvents(0, QEvent::DeferredDelete); - - // and move the object back - obj->moveToThread(orig_thread); - - m.lock(); - loop = 0; - w.wakeOne(); - } - } + virtual void run() + { + m.lock(); + QEventLoop eventLoop; + + while (1) { + // thread now sleeps, waiting for work + w.wakeOne(); + w.wait(&m); + if (do_quit) { + m.unlock(); + break; + } + + loop = &eventLoop; + agent = new SynchronizerAgent; + connect(agent, SIGNAL(started()), SLOT(agent_started()), Qt::DirectConnection); + + // run the event loop + eventLoop.exec(); + + delete agent; + agent = 0; + + // eventloop done, flush pending events + QCoreApplication::instance()->sendPostedEvents(); + QCoreApplication::instance()->sendPostedEvents(0, QEvent::DeferredDelete); + + // and move the object back + obj->moveToThread(orig_thread); + + m.lock(); + loop = 0; + w.wakeOne(); + } + } private slots: - void agent_started() - { - m.unlock(); - } + void agent_started() + { + m.unlock(); + } }; Synchronizer::Synchronizer(QObject *parent) -:QObject(parent) + : QObject(parent) { - d = new Private(parent, this); + d = new Private(parent, this); } Synchronizer::~Synchronizer() { - delete d; + delete d; } bool Synchronizer::waitForCondition(int msecs) { - d->start(); - return d->waitForCondition(msecs); + d->start(); + return d->waitForCondition(msecs); } void Synchronizer::conditionMet() { - d->conditionMet(); + d->conditionMet(); } } diff --git a/src/support/syncthread.cpp b/src/support/syncthread.cpp --- a/src/support/syncthread.cpp +++ b/src/support/syncthread.cpp @@ -25,79 +25,86 @@ #include #include -namespace QCA { +namespace QCA +{ QByteArray methodReturnType(const QMetaObject *obj, const QByteArray &method, const QList argTypes) { - for(int n = 0; n < obj->methodCount(); ++n) - { - QMetaMethod m = obj->method(n); + for (int n = 0; n < obj->methodCount(); ++n) { + QMetaMethod m = obj->method(n); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QByteArray sig = m.methodSignature(); + QByteArray sig = m.methodSignature(); #else - QByteArray sig = m.signature(); + QByteArray sig = m.signature(); #endif - int offset = sig.indexOf('('); - if(offset == -1) - continue; - QByteArray name = sig.mid(0, offset); - if(name != method) - continue; - if(m.parameterTypes() != argTypes) - continue; - - return m.typeName(); - } - return QByteArray(); + int offset = sig.indexOf('('); + if (offset == -1) { + continue; + } + QByteArray name = sig.mid(0, offset); + if (name != method) { + continue; + } + if (m.parameterTypes() != argTypes) { + continue; + } + + return m.typeName(); + } + return QByteArray(); } bool invokeMethodWithVariants(QObject *obj, const QByteArray &method, const QVariantList &args, QVariant *ret, Qt::ConnectionType type) { - // QMetaObject::invokeMethod() has a 10 argument maximum - if(args.count() > 10) - return false; - - QList argTypes; - for(int n = 0; n < args.count(); ++n) - argTypes += args[n].typeName(); - - // get return type - int metatype = QMetaType::Void; - QByteArray retTypeName = methodReturnType(obj->metaObject(), method, argTypes); + // QMetaObject::invokeMethod() has a 10 argument maximum + if (args.count() > 10) { + return false; + } + + QList argTypes; + for (int n = 0; n < args.count(); ++n) { + argTypes += args[n].typeName(); + } + + // get return type + int metatype = QMetaType::Void; + QByteArray retTypeName = methodReturnType(obj->metaObject(), method, argTypes); #if QT_VERSION >= 0x050000 - if(!retTypeName.isEmpty() && retTypeName != "void") + if (!retTypeName.isEmpty() && retTypeName != "void") #else - if(!retTypeName.isEmpty()) + if (!retTypeName.isEmpty()) #endif - { - metatype = QMetaType::type(retTypeName.data()); + { + metatype = QMetaType::type(retTypeName.data()); #if QT_VERSION >= 0x050000 - if(metatype == QMetaType::UnknownType) // lookup failed + if (metatype == QMetaType::UnknownType) // lookup failed #else - if(metatype == QMetaType::Void) // lookup failed + if (metatype == QMetaType::Void) // lookup failed #endif - return false; - } - - QGenericArgument arg[10]; - for(int n = 0; n < args.count(); ++n) - arg[n] = QGenericArgument(args[n].typeName(), args[n].constData()); - - QGenericReturnArgument retarg; - QVariant retval; - - if(metatype != QMetaType::Void) - { - retval = QVariant(metatype, (const void *)0); - retarg = QGenericReturnArgument(retval.typeName(), retval.data()); - } - - if(!QMetaObject::invokeMethod(obj, method.data(), type, retarg, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9])) - return false; - - if(retval.isValid() && ret) - *ret = retval; - return true; + return false; + } + + QGenericArgument arg[10]; + for (int n = 0; n < args.count(); ++n) { + arg[n] = QGenericArgument(args[n].typeName(), args[n].constData()); + } + + QGenericReturnArgument retarg; + QVariant retval; + + if (metatype != QMetaType::Void) { + retval = QVariant(metatype, (const void *)0); + retarg = QGenericReturnArgument(retval.typeName(), retval.data()); + } + + if (!QMetaObject::invokeMethod(obj, method.data(), type, retarg, arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9])) { + return false; + } + + if (retval.isValid() && ret) { + *ret = retval; + } + return true; } //---------------------------------------------------------------------------- @@ -107,129 +114,131 @@ class SyncThread::Private : public QObject { - Q_OBJECT + Q_OBJECT public: - SyncThread *q; - QMutex m; - QWaitCondition w; - QEventLoop *loop; - SyncThreadAgent *agent; - bool last_success; - QVariant last_ret; - - Private(SyncThread *_q) : QObject(_q), q(_q) - { - loop = 0; - agent = 0; - } + SyncThread *q; + QMutex m; + QWaitCondition w; + QEventLoop *loop; + SyncThreadAgent *agent; + bool last_success; + QVariant last_ret; + + Private(SyncThread *_q) : QObject(_q), q(_q) + { + loop = 0; + agent = 0; + } private slots: - void agent_started(); - void agent_call_ret(bool success, const QVariant &ret); + void agent_started(); + void agent_call_ret(bool success, const QVariant &ret); }; class SyncThreadAgent : public QObject { - Q_OBJECT + Q_OBJECT public: - SyncThreadAgent(QObject *parent = 0) : QObject(parent) - { - QMetaObject::invokeMethod(this, "started", Qt::QueuedConnection); - } + SyncThreadAgent(QObject *parent = 0) : QObject(parent) + { + QMetaObject::invokeMethod(this, "started", Qt::QueuedConnection); + } signals: - void started(); - void call_ret(bool success, const QVariant &ret); + void started(); + void call_ret(bool success, const QVariant &ret); public slots: - void call_do(QObject *obj, const QByteArray &method, const QVariantList &args) - { - QVariant ret; - bool ok = invokeMethodWithVariants(obj, method, args, &ret, Qt::DirectConnection); - emit call_ret(ok, ret); - } + void call_do(QObject *obj, const QByteArray &method, const QVariantList &args) + { + QVariant ret; + bool ok = invokeMethodWithVariants(obj, method, args, &ret, Qt::DirectConnection); + emit call_ret(ok, ret); + } }; SyncThread::SyncThread(QObject *parent) -:QThread(parent) + : QThread(parent) { - d = new Private(this); - qRegisterMetaType("QVariant"); - qRegisterMetaType("QVariantList"); + d = new Private(this); + qRegisterMetaType("QVariant"); + qRegisterMetaType("QVariantList"); } SyncThread::~SyncThread() { - stop(); - delete d; + stop(); + delete d; } void SyncThread::start() { - QMutexLocker locker(&d->m); - Q_ASSERT(!d->loop); - QThread::start(); - d->w.wait(&d->m); + QMutexLocker locker(&d->m); + Q_ASSERT(!d->loop); + QThread::start(); + d->w.wait(&d->m); } void SyncThread::stop() { - QMutexLocker locker(&d->m); - if(!d->loop) - return; - QMetaObject::invokeMethod(d->loop, "quit"); - d->w.wait(&d->m); - wait(); + QMutexLocker locker(&d->m); + if (!d->loop) { + return; + } + QMetaObject::invokeMethod(d->loop, "quit"); + d->w.wait(&d->m); + wait(); } QVariant SyncThread::call(QObject *obj, const QByteArray &method, const QVariantList &args, bool *ok) { - QMutexLocker locker(&d->m); - bool ret; - Q_UNUSED(ret); // In really ret is used. I use this hack to suppress a compiler warning - ret = QMetaObject::invokeMethod(d->agent, "call_do", - Qt::QueuedConnection, Q_ARG(QObject*, obj), - Q_ARG(QByteArray, method), Q_ARG(QVariantList, args)); - Q_ASSERT(ret); - d->w.wait(&d->m); - if(ok) - *ok = d->last_success; - QVariant v = d->last_ret; - d->last_ret = QVariant(); - return v; + QMutexLocker locker(&d->m); + bool ret; + Q_UNUSED(ret); // In really ret is used. I use this hack to suppress a compiler warning + ret = QMetaObject::invokeMethod(d->agent, "call_do", + Qt::QueuedConnection, Q_ARG(QObject *, obj), + Q_ARG(QByteArray, method), Q_ARG(QVariantList, args)); + Q_ASSERT(ret); + d->w.wait(&d->m); + if (ok) { + *ok = d->last_success; + } + QVariant v = d->last_ret; + d->last_ret = QVariant(); + return v; } void SyncThread::run() { - d->m.lock(); - d->loop = new QEventLoop; - d->agent = new SyncThreadAgent; - connect(d->agent, SIGNAL(started()), d, SLOT(agent_started()), Qt::DirectConnection); - connect(d->agent, SIGNAL(call_ret(bool, const QVariant &)), d, SLOT(agent_call_ret(bool, const QVariant &)), Qt::DirectConnection); - d->loop->exec(); - d->m.lock(); - atEnd(); - delete d->agent; - delete d->loop; - d->agent = 0; - d->loop = 0; - d->w.wakeOne(); - d->m.unlock(); + d->m.lock(); + d->loop = new QEventLoop; + d->agent = new SyncThreadAgent; + connect(d->agent, SIGNAL(started()), d, SLOT(agent_started()), Qt::DirectConnection); + connect(d->agent, SIGNAL(call_ret(bool,QVariant)), d, SLOT(agent_call_ret(bool,QVariant)), Qt::DirectConnection); + d->loop->exec(); + d->m.lock(); + atEnd(); + delete d->agent; + delete d->loop; + d->agent = 0; + d->loop = 0; + d->w.wakeOne(); + d->m.unlock(); } void SyncThread::Private::agent_started() { - q->atStart(); - w.wakeOne(); - m.unlock(); + q->atStart(); + w.wakeOne(); + m.unlock(); } void SyncThread::Private::agent_call_ret(bool success, const QVariant &ret) { - QMutexLocker locker(&m); - last_success = success; - last_ret = ret; - w.wakeOne(); + QMutexLocker locker(&m); + last_success = success; + last_ret = ret; + w.wakeOne(); } }