# Source: kmdcodec.h |
Annotated List
Files
Globals
Hierarchy
Index

    /*
        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: root@i386.ports.openbsd.org on Wed Apr 25 13:58:13 2001, using kdoc 2.0a53.