|
|
/* Copyright (C) 2000 Dawit Alemayehu <adawit@kde.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. This KMD5 class is based on a C++ implementation of "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by Mordechai T. Abzug, Copyright (c) 1995. The implementation passes the test-suite as defined by RFC 1321. RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992, RSA Data Security, Inc. Created 1991. All rights reserved. The encode/decode utilities in KCodecs were adapted from Ronald Tschalär Copyright (C) 1996-1999 HTTPClient java pacakge. */ #ifndef _KMDBASE_H #define _KMDBASE_H #include <stdio.h> #include <qglobal.h> typedef char HASH[16]; typedef char HASHHEX[33]; #define KBase64 KCodecs class QString; class QCString; class KCodecs { public: /** * This method encodes the given string using the unix uuencode * encoding. * * 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. * * <em>Note:</em> @p data should be just the actual data ; any * 'begin' and 'end' lines such as those generated by *nix * @p uuencode utility must not be included. * * @param data the data * @return the uuencoded <var>data</var> */ static QString uuencode( const QString& data ); /** * This method decodes the given uuencoded string. * * <em>Note:</em> @p data should be just the actual data. * Any 'begin' and 'end' lines such as those generated by * *nix @p uuencode utility must not be included. * * @param data the uuencode-encoded data. * @return the decoded @p data. */ static QString uudecode( const QString& data ); /** * This method encodes the given string using the base64-encoding * specified in RFC-2045 (Section 6.8). It's used for example in * the "Basic" authorization scheme (RFC 2617). * * @param data the string. * @return the base64-encoded string. */ static QString base64Encode( const QString& data ); /** * This method decodes the given string using the * base64-encoding as specified in RFC-2045 (Section 6.8). * * @param data the base64-encoded string. * @return the decoded string. */ static QString base64Decode( const QString& data ); /** * @deprecated. Use base64Encode instead. */ static QString encodeString( const QString& data ) { return base64Encode(data); } /** * @deprecated. Use base64Decode instead. */ static QString decodeString( const QString& data ) { return base64Decode(data); } private: KCodecs(); }; /** * * This class provides an easy to use C++ implementation of the MD5 * algorithm. It provides an easy way to use the class much like * you would the plain C-implementations along with single shot * constructors that automatically perform the update and call * @ref finalize. * * The default constructor is intended to provide much the same * functionality as the C-implementation while the other three * constructors are used to perform quick digest calculations whenever * the message to be does not require subsequent updating. Additionally, * you can obtain either the result in a 16-byte binary format or * 33-byte hexidecimal by invoking @ref rawDigest and @ hexDigest * respectivelly. NOTE the extra byte in the latter format is is a * NULL character to terminate the string. * * @sect Example: * * The simplest way of using this class through one of the * accessor methods: * * <PRE> * KMD5 context( QCString("ONE") ); * printf ( "Raw Digest output: %s", static_cast<char*>(context.rawDigest() ); * printf ( "Hex Digest output: %s", context.hexDigest() ); * </PRE> * * You can then invoke @ref reset() to re-use the same class to perform * another digest. * * context.reset(); * context.update( QCString("TWO") ); * context.update( QCString("THREE") ); * printf ( "Raw Digest output: %s", static_cast<char*>(context.rawDigest() ); * printf ( "Hex Digest output: %s", context.hexDigest() ); * * Note that once you invoke @ref reset(), the previouly calculated * digest value will be lost. Thus, be sure you copy the result if * you need to use it again. Also you cannot invoke update() if you * use one of the convienence constructors unless you first invoke * reset(). Hence, if you need to update the message to be digested, * it is better to use the default constructor to avoid this subtle * error. * * The conventional (C-implemetation like) method of using this class: * * <PRE> * KMD5 context; * context.update(QCString("ONE")); * context.update(QCString("TWO")); * context.update(QCString("THREE")); * context.finalize(); * printf ( "Raw Digest output: %s", static_cast<char*>(context.rawDigest() ); * printf ( "Hex Digest output: %s", context.hexDigest() ); * </PRE> * * @short An adapted C++ implementation of RSA Data Securities MD5 algorithm. * @author Dawit Alemayheu <adawit@kde.org> */ class KMD5 { public: /** * HEX hexidecimal representation of the message digest * BIN binary representation of the message digest */ enum DigestType { BIN, HEX }; /** * ERR_NONE no error occured. [default] * ERR_ALREADY_FINALIZED @ref finalize() has already been invoked. * ERR_NOT_YET_FINALIZED @ref digest() or @ref rawDigest() invoked before finalize(). * ERR_CANNOT_READ_FILE indicates a problem while trying to read the given file. * ERR_CANNOT_CLOSE_FILE indicates a problem while trying to close the given file. */ enum ErrorType { ERR_NONE, ERR_ALREADY_FINALIZED, ERR_NOT_YET_FINALIZED, ERR_CANNOT_READ_FILE, ERR_CANNOT_CLOSE_FILE }; /** * Default constructor that only performs initialization. * Unlike the other constructors */ KMD5(); /** * Constructor that initializes, computes, and finalizes * the message digest for the given file. * * NOTE: This is a convience constructor. As such it does * not allow the update of the message after it has been * invoked. If you need to update the message after creating * the constructor, */ KMD5(FILE *file); /** * Constructor that initializes, computes, and finalizes * the message digest for the given string. */ KMD5(Q_UINT8 * input); // digest string, finalize /** * Same as above except it takes a QCString as input. */ KMD5(const QCString& input); /** * Same as above except it takes a QString as input. */ KMD5(const QString& input); /** * Updates the message to be digested. * * @param input message to be added to digest (unsigned char*) * @param len the length of the given message. */ void update (Q_UINT8 * input, int len = -1 ); /** * Same as above except except it takes a QCString as the argument. */ void update ( const QCString& input ); /** * Same as above except it takes a QString as the argument. */ void update ( const QString& input ); /** * Same as above except it accepts a pointer to FILE. * * NOTE that the file must have been already opened. If you * want the file to be automatically closed, set @p closeFile * to TRUE. * * @param file a pointer to FILE as returned by calls like f{d,re}open * @param closeFile if true closes the file using fclose. */ void update (FILE *file, bool closeFile = false ); /** * Finalizes the message digest calculation. * * If you used the default constructor, you must invoke this function * before you can obtain the calculated digest value. */ void finalize(); /** * Compares the message digest supplied messaged digest @p msg_digest * with the one calculated for the input QCString @p input. * * NOTE: Calling this function will reset any previously calcualted * digests. If you want to verify your token with the current digest * value, use @ref verify( const char*, DigestType ) instead. * * @param input the message to be added to the digest value * @param msg_digest the digest to compare the result against * @param type the format of the result for comparison (binary or hexidecimal). * * @return true if the digests match, otherwise false. */ bool verify( const QCString& input, const char * msg_digest, DigestType type = HEX ); /** * Same as above except the input is a QString instead. * * NOTE: Calling this function will reset any previously calcualted * digests. If you want to verify your token with the current digest * value, use @ref verify( const char*, DigestType ) instead. */ bool verify( const QString& input, const char * msg_digest, DigestType type = HEX ); /** * Same as above except the input is a pointer for a FILE instead. * * NOTE: Calling this function will reset any previously calcualted * digests. If you want to verify your token with the current digest * value, use @ref verify( const char*, DigestType ) instead. */ bool verify( FILE* f, const char * msg_digest, DigestType type = HEX ); /** * Compares the given string with with the current message digest. * * NOTE: Unlike the other verify functions this one does not reset * the current message digest if one is already present. It is meant * to allow you to compare against the existing message digest. Also * note that this function will return false if a digest has yet to be * calculated. * * @param msg_digest the digest to compare the result against * @param type the format of the result for comparison (binary or hexidecimal). * * @return true if the digests match, otherwise false. */ bool verify( const char* msg_digest, DigestType type = HEX ); /** * Re-initializes internal paramters. * * Note that calling this function will reset all internal variables * and hence any calculated digest. Invoke this function only when * you have to re-use the same object to perform another message digest * calculation. */ void reset(); /** * Returns the raw 16-byte binary value of the message digest. * * NOTE: you are responsible for making a copy of this string. */ Q_UINT8* rawDigest (); // digest as a 16-byte binary array /** * 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] ) * @return true if the raw digest is ready, otherwise false. */ void rawDigest( HASH bin ); /** * Returns a the value of the calculated message digest. * This is a 32 byte hexidecimal value terminated by a NULL * character. * * NOTE: you are responsible for making a copy of this string. */ char * hexDigest (); // digest as a 33-byte ascii-hex string /** * Fills the given array with the hexcidecimal 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. Also note that this * method will append a terminating NULL charater. * * @param bin an array of 33 characters ( char[33] ) * @return true if the digest is ready, otherwise false. */ void hexDigest( HASHHEX hex ); /** * Indicates whether the message digest calculation failed * or succeeded. Use @ref error to determine the error type. * * @return true if */ bool hasErrored() const { return (m_error != ERR_NONE); } /** * Returns the type error that occurred. See @ref ErrorType * for descriptions. */ int error() const { return m_error; } protected: /** * Initializer called by all constructors */ void init(); /** * Performs the real update work. Note * that length is implied to be 64. */ void transform( Q_UINT8 * buffer ); /** * Returns true if the current message digest matches @p msg_digest. */ bool isDigestMatch( const char * msg_digest, DigestType type ); private: Q_UINT32 m_state[4]; Q_UINT32 m_count[2]; // number of *bits*, mod 2^64 Q_UINT8 m_buffer[64]; // input buffer Q_UINT8 m_digest[16]; ErrorType m_error; bool m_finalized; struct KMD5Private; KMD5Private* d; }; #endif
Generated by: faure on ftp.kde.com on Wed Jun 20 13:26:37 2001, using kdoc 2.0a53. |