/* Copyright (C) 2000-2001 Dawit Alemayehu Copyright (C) 2001 Rik Hemsley (rikkus) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992. RSA Data Security, Inc. Created 1991. All rights reserved. The KMD5 class is based on a C++ implementation of "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by Mordechai T. Abzug, Copyright (c) 1995. This implementation passes the test-suite as defined in RFC 1321. The encoding and decoding utilities in KCodecs with the exception of quoted-printable are based on the java implementation in HTTPClient package by Ronald Tschalär Copyright (C) 1996-1999. The quoted-printable codec as described in RFC 2045, section 6.7. is by Rik Hemsley (C) 2001. */ #ifndef _KMDBASE_H #define _KMDBASE_H #define KBase64 KCodecs #include #include #include #include "tdelibs_export.h" /** * A wrapper class for the most commonly used encoding and * decoding algorithms. Currently there is support for encoding * and decoding input using base64, uu and the quoted-printable * specifications. * * \b Usage: * * \code * TQCString input = "Aladdin:open sesame"; * TQCString result = KCodecs::base64Encode(input); * cout << "Result: " << result.data() << endl; * \endcode * *
 * Output should be
 * Result: QWxhZGRpbjpvcGVuIHNlc2FtZQ==
 * 
* * The above example makes use of the convenience functions * (ones that accept/return null-terminated strings) to encode/decode * a string. If what you need is to encode or decode binary data, then * it is highly recommended that you use the functions that take an input * and output TQByteArray as arguments. These functions are specifically * tailored for encoding and decoding binary data. * * @short A collection of commonly used encoding and decoding algorithms. * @author Dawit Alemayehu * @author Rik Hemsley */ class TDECORE_EXPORT KCodecs { public: /** * Encodes the given data using the quoted-printable algorithm. * * @param in data to be encoded. * @param useCRLF if true the input data is expected to have * CRLF line breaks and the output will have CRLF line * breaks, too. * @return quoted-printable encoded string. */ static TQCString quotedPrintableEncode(const TQByteArray & in, bool useCRLF = true); /** * @overload * * Same as above except it accepts a null terminated * string instead an array. * * @param str string to be encoded. * @param useCRLF if true the input data is expected to have * CRLF line breaks and the output will have CRLF line * breaks, too. * @return quoted-printable encoded string. */ static TQCString quotedPrintableEncode(const TQCString & str, bool useCRLF = true); /** * Encodes the given data using the quoted-printable algorithm. * * Use this function if you want the result of the encoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for encoding binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be encoded. * @param out encoded data. * @param useCRLF if true the input data is expected to have * CRLF line breaks and the output will have CRLF line * breaks, too. */ static void quotedPrintableEncode(const TQByteArray & in, TQByteArray& out, bool useCRLF); /** * Decodes a quoted-printable encoded data. * * Accepts data with CRLF or standard unix line breaks. * * @param in data to be decoded. * @return decoded string. */ static TQCString quotedPrintableDecode(const TQByteArray & in); /** * @overload * * Same as above except it accepts a null terminated * string instead an array. * * @param str string to be decoded. * @return decoded string. */ static TQCString quotedPrintableDecode(const TQCString & str); /** * Decodes a quoted-printable encoded data. * * Accepts data with CRLF or standard unix line breaks. * Use this function if you want the result of the decoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for decoding an encoded * binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be decoded. * @param out decoded data. */ static void quotedPrintableDecode(const TQByteArray & in, TQByteArray& out); /** * Encodes the given data using the uuencode algorithm. * * The output is split into lines starting with the number of * encoded octets in the line and ending with a newline. No * line is longer than 45 octets (60 characters), excluding the * line terminator. * * @param in data to be uuencoded * @return uuencoded string. */ static TQCString uuencode( const TQByteArray& in ); /** * @overload * * Same as the above functions except it accepts * a null terminated string instead an array. * * @param str string to be uuencoded. * @return encoded string. */ static TQCString uuencode( const TQCString& str ); /** * Encodes the given data using the uuencode algorithm. * * Use this function if you want the result of the encoding * to be placed in another array and cut down the number of * copy operation that have to be performed in the process. * This is the preffered method for encoding binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be uuencoded. * @param out uudecoded data. */ static void uuencode( const TQByteArray& in, TQByteArray& out ); /** * Decodes the given data using the uudecode algorithm. * * Any 'begin' and 'end' lines like those generated by * the utilities in unix and unix-like OS will be * automatically ignored. * * @param in data to be decoded. * @return decoded string. */ static TQCString uudecode( const TQByteArray& in ); /** * @overload * * Same as the above functions except it accepts * a null terminated string instead an array. * * @param str string to be decoded. * @return uudecoded string. */ static TQCString uudecode( const TQCString& str ); /** * Decodes the given data using the uudecode algorithm. * * Use this function if you want the result of the decoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is the preferred method for decoding binary data. * * Any 'begin' and 'end' lines like those generated by * the utilities in unix and unix-like OS will be * automatically ignored. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be decoded. * @param out uudecoded data. */ static void uudecode( const TQByteArray& in, TQByteArray& out ); /** * Encodes the given data using the base64 algorithm. * * The boolean argument determines if the encoded data is * going to be restricted to 76 characters or less per line * as specified by RFC 2045. If @p insertLFs is true, then * there will be 76 characters or less per line. * * @param in data to be encoded. * @param insertLFs limit the number of characters per line. * * @return base64 encoded string. */ static TQCString base64Encode( const TQByteArray& in, bool insertLFs = false); /** * @overload * * Same as the above functions except it accepts * a null terminated string instead an array. * * @param str string to be encoded. * @param insertLFs limit the number of characters per line. * @return decoded string. */ static TQCString base64Encode( const TQCString& str, bool insertLFs = false ); /** * Encodes the given data using the base64 algorithm. * * Use this function if you want the result of the encoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for encoding binary data. * * The boolean argument determines if the encoded data is going * to be restricted to 76 characters or less per line as specified * by RFC 2045. If @p insertLFs is true, then there will be 76 * characters or less per line. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be encoded. * @param out encoded data. * @param insertLFs limit the number of characters per line. */ static void base64Encode( const TQByteArray& in, TQByteArray& out, bool insertLFs = false ); /** * Decodes the given data that was encoded using the * base64 algorithm. * * @param in data to be decoded. * @return decoded string. */ static TQCString base64Decode( const TQByteArray& in ); /** * @overload * * Same as the above functions except it accepts * a null terminated string instead an array. * * @param str string to be decoded. * @return decoded string. */ static TQCString base64Decode( const TQCString& str ); /** * Decodes the given data that was encoded with the base64 * algorithm. * * Use this function if you want the result of the decoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for decoding an encoded * binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be decoded. * @param out decoded data. */ static void base64Decode( const TQByteArray& in, TQByteArray& out ); private: KCodecs(); private: static const char UUEncMap[64]; static const char UUDecMap[128]; static const char Base64EncMap[64]; static const char Base64DecMap[128]; static const char hexChars[16]; static const unsigned int maxQPLineLength; }; class KMD5Private; /** * @short An adapted C++ implementation of RSA Data Securities MD5 algorithm. * * The default constructor is designed to provide much the same * functionality as the most commonly used C-implementation, while * the other three constructors are meant to further simplify the * process of obtaining a digest by calculating the result in a * single step. * * KMD5 is state-based, that means you can add new contents with * update() as long as you didn't request the digest value yet. * After the digest value was requested, the object is "finalized" * and you have to call reset() to be able to do another calculation * with it. The reason for this behavior is that upon requesting * the message digest KMD5 has to pad the received contents up to a * 64 byte boundary to calculate its value. After this operation it * is not possible to resume consuming data. * * \b Usage: * * A common usage of this class: * * \code * const char* test1; * KMD5::Digest rawResult; * * test1 = "This is a simple test."; * KMD5 context (test1); * cout << "Hex Digest output: " << context.hexDigest().data() << endl; * \endcode * * To cut down on the unnecessary overhead of creating multiple KMD5 * objects, you can simply invoke reset() to reuse the same object * in making another calculation: * * \code * context.reset (); * context.update ("TWO"); * context.update ("THREE"); * cout << "Hex Digest output: " << context.hexDigest().data() << endl; * \endcode * * @author Dirk Mueller , Dawit Alemayehu */ class TDECORE_EXPORT KMD5 { public: typedef unsigned char Digest[16]; KMD5(); /** * Constructor that updates the digest for the given string. * * @param in C string or binary data * @param len if negative, calculates the length by using * strlen on the first parameter, otherwise * it trusts the given length (does not stop on NUL byte). */ KMD5(const char* in, int len = -1); /** * @overload * * Same as above except it accepts a TQByteArray as its argument. */ KMD5(const TQByteArray& a ); /** * @overload * * Same as above except it accepts a TQCString as its argument. */ KMD5(const TQCString& a ); /** * Updates the message to be digested. Be sure to add all data * before you read the digest. After reading the digest, you * can not add more data! * * @param in message to be added to digest * @param len the length of the given message. */ void update(const char* in, int len = -1) { update(reinterpret_cast(in), len); } /** * @overload */ void update(const unsigned char* in, int len = -1); /** * @overload * * @param in message to be added to the digest (TQByteArray). */ void update(const TQByteArray& in ); /** * @overload * * @param in message to be added to the digest (TQCString). */ void update(const TQCString& in ); /** * @overload * * reads the data from an I/O device, i.e. from a file (TQFile). * * NOTE that the file must be open for reading. * * @param file a pointer to FILE as returned by calls like f{d,re}open * * @returns false if an error occurred during reading. */ bool update(TQIODevice& file); /** * Calling this function will reset the calculated message digest. * Use this method to perform another message digest calculation * without recreating the KMD5 object. */ void reset(); /** * @return the raw representation of the digest */ const Digest& rawDigest (); /** * Fills the given array with the binary representation of the * message digest. * * Use this method if you do not want to worry about making * copy of the digest once you obtain it. * * @param bin an array of 16 characters ( char[16] ) */ void rawDigest( KMD5::Digest& bin ); /** * Returns the value of the calculated message digest in * a hexadecimal representation. */ TQCString hexDigest (); /** * @overload */ void hexDigest(TQCString&); /** * Returns the value of the calculated message digest in * a base64-encoded representation. */ TQCString base64Digest (); /** * returns true if the calculated digest for the given * message matches the given one. */ bool verify( const KMD5::Digest& digest); /** * @overload */ bool verify(const TQCString&); protected: /** * Performs the real update work. Note * that length is implied to be 64. */ void transform( const unsigned char buffer[64] ); /** * finalizes the digest */ void finalize(); private: KMD5(const KMD5& u); KMD5& operator=(const KMD5& md); void init(); void encode( unsigned char* output, TQ_UINT32 *in, TQ_UINT32 len ); void decode( TQ_UINT32 *output, const unsigned char* in, TQ_UINT32 len ); TQ_UINT32 rotate_left( TQ_UINT32 x, TQ_UINT32 n ); TQ_UINT32 F( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z ); TQ_UINT32 G( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z ); TQ_UINT32 H( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z ); TQ_UINT32 I( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z ); void FF( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d, TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac ); void GG( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d, TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac ); void HH( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d, TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac ); void II( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d, TQ_UINT32 x, TQ_UINT32 s, TQ_UINT32 ac ); private: TQ_UINT32 m_state[4]; TQ_UINT32 m_count[2]; TQ_UINT8 m_buffer[64]; Digest m_digest; bool m_finalized; KMD5Private* d; }; /** * @short An adapted C++ implementation of the MD4 Message-Digest algorithm. * @since 3.4 * * The class usage is the same as KMD5. */ class TDECORE_EXPORT KMD4 { public: typedef unsigned char Digest[16]; KMD4(); /** * Constructor that updates the digest for the given string. * * @param in C string or binary data * @param len if negative, calculates the length by using * strlen on the first parameter, otherwise * it trusts the given length (does not stop on NUL byte). */ KMD4(const char* in, int len = -1); /** * @overload * * Same as above except it accepts a TQByteArray as its argument. */ KMD4(const TQByteArray& a ); /** * @overload * * Same as above except it accepts a TQCString as its argument. */ KMD4(const TQCString& a ); /** * Updates the message to be digested. Be sure to add all data * before you read the digest. After reading the digest, you * can not add more data! * * @param in message to be added to digest * @param len the length of the given message. */ void update(const char* in, int len = -1) { update(reinterpret_cast(in), len); } /** * @overload */ void update(const unsigned char* in, int len = -1); /** * @overload * * @param in message to be added to the digest (TQByteArray). */ void update(const TQByteArray& in ); /** * @overload * * @param in message to be added to the digest (TQCString). */ void update(const TQCString& in ); /** * @overload * * reads the data from an I/O device, i.e. from a file (TQFile). * * NOTE that the file must be open for reading. * * @param file a pointer to FILE as returned by calls like f{d,re}open * * @returns false if an error occurred during reading. */ bool update(TQIODevice& file); /** * Calling this function will reset the calculated message digest. * Use this method to perform another message digest calculation * without recreating the KMD4 object. */ void reset(); /** * @return the raw representation of the digest */ const Digest& rawDigest (); /** * Fills the given array with the binary representation of the * message digest. * * Use this method if you do not want to worry about making * copy of the digest once you obtain it. * * @param bin an array of 16 characters ( char[16] ) */ void rawDigest( KMD4::Digest& bin ); /** * Returns the value of the calculated message digest in * a hexadecimal representation. */ TQCString hexDigest (); /** * @overload */ void hexDigest(TQCString&); /** * Returns the value of the calculated message digest in * a base64-encoded representation. */ TQCString base64Digest (); /** * returns true if the calculated digest for the given * message matches the given one. */ bool verify( const KMD4::Digest& digest); /** * @overload */ bool verify(const TQCString&); protected: /** * Performs the real update work. Note * that length is implied to be 64. */ void transform( TQ_UINT32 buf[4], TQ_UINT32 const in[16] ); /** * finalizes the digest */ void finalize(); private: KMD4(const KMD4& u); KMD4& operator=(const KMD4& md); void init(); void byteReverse( unsigned char *buf, TQ_UINT32 len ); TQ_UINT32 rotate_left( TQ_UINT32 x, TQ_UINT32 n ); TQ_UINT32 F( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z ); TQ_UINT32 G( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z ); TQ_UINT32 H( TQ_UINT32 x, TQ_UINT32 y, TQ_UINT32 z ); void FF( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d, TQ_UINT32 x, TQ_UINT32 s ); void GG( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d, TQ_UINT32 x, TQ_UINT32 s ); void HH( TQ_UINT32& a, TQ_UINT32 b, TQ_UINT32 c, TQ_UINT32 d, TQ_UINT32 x, TQ_UINT32 s ); private: TQ_UINT32 m_state[4]; TQ_UINT32 m_count[2]; TQ_UINT8 m_buffer[64]; Digest m_digest; bool m_finalized; class KMD4Private; KMD4Private* d; }; #endif