/*
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., 675 Mass Ave, Cambridge, MA 02139, 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
/**
* 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.
*
* @sect Usage:
*
*
* QCString input = "Aladdin:open sesame";
* QCString result = KCodecs::base64Encode(input);
* cout << "Result: " << result.data() << endl;
*
* 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 QByteArray 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 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 data.
*/
static QCString quotedPrintableEncode(const QByteArray & in,
bool useCRLF = true);
/**
* @overload
*
* Same as above except it accepts a null terminated
* string instead an array.
*
* @param str 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 data.
*/
static QCString quotedPrintableEncode(const QCString & 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 decoded data.
* @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 data.
*/
static void quotedPrintableEncode(const QByteArray & in, QByteArray& out,
bool useCRLF);
/**
* Decodes a quoted-printable encoded string.
*
* Accepts data with CRLF or standard unix line breaks.
*
* @param in the data to be decoded.
* @return decoded data.
*/
static QCString quotedPrintableDecode(const QByteArray & in);
/**
* @overload
*
* Same as above except it accepts a null terminated
* string instead an array.
*
* @param str the data to be decoded.
* @return decoded data.
*/
static QCString quotedPrintableDecode(const QCString & 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 encoded.
* @param out decoded data.
*
* @return quoted-printable encoded data.
*/
static void quotedPrintableDecode(const QByteArray & in, QByteArray& 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 the data to be uuencoded
* @return a uuencoded data.
*/
static QCString uuencode( const QByteArray& in );
/**
* @overload
*
* Same as the above functions except it accepts
* a null terminated string instead an array.
*
* @param str the string to be uuencoded.
* @return the encoded string.
*/
static QCString uuencode( const QCString& 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 the data to be uuencoded.
* @param out the container for the uudecoded data.
*/
static void uuencode( const QByteArray& in, QByteArray& out );
/**
* Decodes the given data using the uuencode algorithm.
*
* Any 'begin' and 'end' lines like those generated by
* the utilities in unix and unix-like OS will be
* automatically ignored.
*
* @param in the data uuencoded data to be decoded.
* @return a decoded string.
*/
static QCString uudecode( const QByteArray& in );
/**
* @overload
*
* Same as the above functions except it accepts
* a null terminated string instead an array.
*
* @param str the string to be decoded.
* @return a uudecoded string.
*/
static QCString uudecode( const QCString& 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 the uuencoded-data to be decoded.
* @param out the container for the uudecoded data.
*/
static void uudecode( const QByteArray& in, QByteArray& 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 the data to be encoded.
* @param insertLFs limit the number of characters per line.
*
* @return a base64 encoded string.
*/
static QCString base64Encode( const QByteArray& in, bool insertLFs = false);
/**
* @overload
*
* Same as the above functions except it accepts
* a null terminated string instead an array.
*
* @param str the string to be encoded.
* @param insertLFs limit the number of characters per line.
* @return the decoded string.
*/
static QCString base64Encode( const QCString& 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 the data to be encoded using base64.
* @param out the container for the encoded data.
* @param insertLFs limit the number of characters per line.
*/
static void base64Encode( const QByteArray& in, QByteArray& out,
bool insertLFs = false );
/**
* Decodes the given data that was encoded using the
* base64 algorithm.
*
* @param in the base64-encoded data to be decoded.
* @return the decoded data.
*/
static QCString base64Decode( const QByteArray& in );
/**
* @overload
*
* Same as the above functions except it accepts
* a null terminated string instead an array.
*
* @param str the base64-encoded string.
* @return the decoded string.
*/
static QCString base64Decode( const QCString& 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 the encoded data to be decoded.
* @param out the container for the decoded data.
*/
static void base64Decode( const QByteArray& in, QByteArray& 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;
/**
* Provides an easy to use C++ implementation of RSA's
* 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 behaviour 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.
*
* @sect Usage:
*
* A common usage of this class:
*
*
* const char* test1;
* KMD5::Digest rawResult;
*
* test1 = "This is a simple test.";
* KMD5 context (test1);
* cout << "Hex Digest output: " << context.hexDigest().data() << endl;
*
*
* To cut down on the unnecessary overhead of creating multiple KMD5
* objects, you can simply invoke @ref reset() to reuse the same object
* in making another calculation:
*
*
* context.reset ();
* context.update ("TWO");
* context.update ("THREE");
* cout << "Hex Digest output: " << context.hexDigest().data() << endl;
*
*
* @short An adapted C++ implementation of RSA Data Securities MD5 algorithm.
* @author Dirk Mueller , Dawit Alemayehu
*/
class 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 QByteArray as its argument.
*/
KMD5(const QByteArray& a );
/**
* @overload
*
* Same as above except it accepts a QByteArray as its argument.
*/
KMD5(const QCString& 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 (QByteArray).
*/
void update(const QByteArray& in );
/**
* @overload
*
* @param in message to be added to the digest (QByteArray).
*/
void update(const QCString& in );
/**
* @overload
*
* reads the data from an I/O device, i.e. from a file (QFile).
*
* 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 occured during reading.
*/
bool update(QIODevice& 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.
*/
QCString hexDigest ();
/**
* @overload
*/
void hexDigest(QCString&);
/**
* Returns the value of the calculated message digest in
* a base64-encoded representation.
*/
QCString 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 QCString&);
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, Q_UINT32 *in, Q_UINT32 len );
void decode( Q_UINT32 *output, const unsigned char* in, Q_UINT32 len );
Q_UINT32 rotate_left( Q_UINT32 x, Q_UINT32 n );
Q_UINT32 F( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
Q_UINT32 G( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
Q_UINT32 H( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
Q_UINT32 I( Q_UINT32 x, Q_UINT32 y, Q_UINT32 z );
void FF( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
Q_UINT32 s, Q_UINT32 ac );
void GG( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
Q_UINT32 s, Q_UINT32 ac );
void HH( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
Q_UINT32 s, Q_UINT32 ac );
void II( Q_UINT32& a, Q_UINT32 b, Q_UINT32 c, Q_UINT32 d, Q_UINT32 x,
Q_UINT32 s, Q_UINT32 ac );
private:
Q_UINT32 m_state[4];
Q_UINT32 m_count[2];
Q_UINT8 m_buffer[64];
Digest m_digest;
bool m_finalized;
KMD5Private* d;
};
#endif
Generated by: caleb on tcdevel on Tue Jan 28 12:54:04 2003, using kdoc $. |