Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

cryptlib.h

Go to the documentation of this file.
00001 // cryptlib.h - written and placed in the public domain by Wei Dai
00002 /*! \file
00003         This file contains the declarations for the abstract base
00004         classes that provide a uniform interface to this library.
00005 */
00006 
00007 /*!     \mainpage <a href="http://www.cryptopp.com">Crypto++</a><sup><small>TM</small></sup> Library 5.1 Reference Manual
00008 <dl>
00009 <dt>Abstract Base Classes<dd>
00010         cryptlib.h
00011 <dt>Symmetric Ciphers<dd>
00012         SymmetricCipherDocumentation
00013 <dt>Hash Functions<dd>
00014         HAVAL, MD2, MD4, MD5, PanamaHash, RIPEMD160, SHA, SHA256, SHA384, SHA512, Tiger
00015 <dt>Non-Cryptographic Checksums<dd>
00016         CRC32, Adler32
00017 <dt>Message Authentication Codes<dd>
00018         #MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC
00019 <dt>Random Number Generators<dd>
00020         NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG
00021 <dt>Public Key Cryptosystems<dd>
00022         DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES
00023 <dt>Public Key Signature Schemes<dd>
00024         DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RabinSS, RWSS, ESIGN
00025 <dt>Key Agreement<dd>
00026         #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH
00027 <dt>Algebraic Structures<dd>
00028         Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver,
00029         ModularArithmetic, MontgomeryRepresentation, GFP2_ONB,
00030         GF2NP, GF256, GF2_32, EC2N, ECP
00031 <dt>Secret Sharing and Information Dispersal<dd>
00032         SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery
00033 <dt>Compression<dd>
00034         Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor
00035 <dt>Input Source Classes<dd>
00036         StringSource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource
00037 <dt>Output Sink Classes<dd>
00038         StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink
00039 <dt>Filter Wrappers<dd>
00040         StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter
00041 <dt>Binary to Text Encoders and Decoders<dd>
00042         HexEncoder, HexDecoder, Base64Encoder, Base64Decoder
00043 <dt>Wrappers for OS features<dd>
00044         Timer, Socket, WindowsHandle, ThreadLocalStorage
00045 <dt>FIPS 140 related<dd>
00046         fips140.h
00047 </dl>
00048 
00049 <p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions.
00050 <p>Click <a href="CryptoPPRef.zip">here</a> to download a zip archive containing this manual.
00051 <p>Thanks to Ryan Phillips for providing the Doxygen configuration file
00052 and getting me started with this manual.
00053 */
00054 
00055 #ifndef CRYPTOPP_CRYPTLIB_H
00056 #define CRYPTOPP_CRYPTLIB_H
00057 
00058 #include "cryptopp_config.h"
00059 #include <limits.h>
00060 #include <exception>
00061 #include <string>
00062 #include <typeinfo>
00063 #include <assert.h>
00064 
00065 NAMESPACE_BEGIN(CryptoPP)
00066 
00067 // forward declarations
00068 class Integer;
00069 
00070 //! used to specify a direction for a cipher to operate in (encrypt or decrypt)
00071 enum CipherDir {ENCRYPTION,     DECRYPTION};
00072 
00073 //! used to represent infinite time
00074 const unsigned long INFINITE_TIME = ULONG_MAX;
00075 
00076 // VC60 workaround: using enums as template parameters causes problems
00077 template <typename ENUM_TYPE, int VALUE>
00078 struct EnumToType
00079 {
00080         static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;}
00081 };
00082 
00083 enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1};
00084 typedef EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian;
00085 typedef EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian;
00086 
00087 //! base class for all exceptions thrown by Crypto++
00088 class Exception : public std::exception
00089 {
00090 public:
00091         //! error types
00092         enum ErrorType {
00093                 //! a method is not implemented
00094                 NOT_IMPLEMENTED,
00095                 //! invalid function argument
00096                 INVALID_ARGUMENT,
00097                 //! BufferedTransformation received a Flush(true) signal but can't flush buffers
00098                 CANNOT_FLUSH,
00099                 //! data integerity check (such as CRC or MAC) failed
00100                 DATA_INTEGRITY_CHECK_FAILED,
00101                 //! received input data that doesn't conform to expected format
00102                 INVALID_DATA_FORMAT,
00103                 //! error reading from input device or writing to output device
00104                 IO_ERROR,
00105                 //! some error not belong to any of the above categories
00106                 OTHER_ERROR
00107         };
00108 
00109         explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {}
00110         virtual ~Exception() throw() {}
00111         const char *what() const throw() {return (m_what.c_str());}
00112         const std::string &GetWhat() const {return m_what;}
00113         void SetWhat(const std::string &s) {m_what = s;}
00114         ErrorType GetErrorType() const {return m_errorType;}
00115         void SetErrorType(ErrorType errorType) {m_errorType = errorType;}
00116 
00117 private:
00118         ErrorType m_errorType;
00119         std::string m_what;
00120 };
00121 
00122 //! exception thrown when an invalid argument is detected
00123 class InvalidArgument : public Exception
00124 {
00125 public:
00126         explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {}
00127 };
00128 
00129 //! exception thrown by decryption filters when trying to decrypt an invalid ciphertext
00130 class InvalidDataFormat : public Exception
00131 {
00132 public:
00133         explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {}
00134 };
00135 
00136 //! exception thrown by decryption filters when trying to decrypt an invalid ciphertext
00137 class InvalidCiphertext : public InvalidDataFormat
00138 {
00139 public:
00140         explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {}
00141 };
00142 
00143 //! exception thrown by a class if a non-implemented method is called
00144 class NotImplemented : public Exception
00145 {
00146 public:
00147         explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {}
00148 };
00149 
00150 //! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers
00151 class CannotFlush : public Exception
00152 {
00153 public:
00154         explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {}
00155 };
00156 
00157 //! error reported by the operating system
00158 class OS_Error : public Exception
00159 {
00160 public:
00161         OS_Error(ErrorType errorType, const std::string s, const std::string& operation, int errorCode)
00162                 : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {}
00163         ~OS_Error() throw() {}
00164 
00165         // the operating system API that reported the error
00166         const std::string & GetOperation() const {return m_operation;}
00167         // the error code return by the operating system
00168         int GetErrorCode() const {return m_errorCode;}
00169 
00170 protected:
00171         std::string m_operation;
00172         int m_errorCode;
00173 };
00174 
00175 //! used to return decoding results
00176 struct DecodingResult
00177 {
00178         explicit DecodingResult() : isValidCoding(false), messageLength(0) {}
00179         explicit DecodingResult(unsigned int len) : isValidCoding(true), messageLength(len) {}
00180 
00181         bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;}
00182         bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);}
00183 
00184         bool isValidCoding;
00185         unsigned int messageLength;
00186 
00187 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00188         operator unsigned int() const {return isValidCoding ? messageLength : 0;}
00189 #endif
00190 };
00191 
00192 //! interface for retrieving values given their names
00193 /*! This class is used to safely pass a variable number of arbitrarily typed arguments to functions
00194         and to read values from keys and crypto parameters.
00195         To get a value, you need to know the name and the type of the value. 
00196         Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports.
00197         Then look at the Name namespace documentation to see what the type of each value is, or
00198         alternatively, call GetIntValue() with the value name, and if the type is not int, a
00199         ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.
00200 */
00201 class NameValuePairs
00202 {
00203 public:
00204         virtual ~NameValuePairs() {}
00205 
00206         //! exception thrown when trying to retrieve a value using a different type than expected
00207         class ValueTypeMismatch : public InvalidArgument
00208         {
00209         public:
00210                 ValueTypeMismatch(std::string name, const std::type_info &stored, const std::type_info &retrieving)
00211                         : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'")
00212                         , m_stored(stored), m_retrieving(retrieving) {}
00213 
00214                 const std::type_info & GetStoredTypeInfo() const {return m_stored;}
00215                 const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;}
00216 
00217         private:
00218                 const std::type_info &m_stored;
00219                 const std::type_info &m_retrieving;
00220         };
00221 
00222         //! get a copy of this object or a subobject of it
00223         template <class T>
00224         bool GetThisObject(T &object) const
00225         {
00226                 return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object);
00227         }
00228 
00229         //! get a pointer to this object, as a pointer to T
00230         template <class T>
00231         bool GetThisPointer(T *&p) const
00232         {
00233                 return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p);
00234         }
00235 
00236         //! get a named value, returns true if the name exists
00237         template <class T>
00238         bool GetValue(const char *name, T &value) const
00239         {
00240                 return GetVoidValue(name, typeid(T), &value);
00241         }
00242 
00243         //! get a named value, returns the default if the name doesn't exist
00244         template <class T>
00245         T GetValueWithDefault(const char *name, T defaultValue) const
00246         {
00247                 GetValue(name, defaultValue);
00248                 return defaultValue;
00249         }
00250 
00251         //! get a list of value names that can be retrieved
00252         std::string GetValueNames() const
00253                 {std::string result; GetValue("ValueNames", result); return result;}
00254 
00255         //! get a named value with type int
00256         /*! used to ensure we don't accidentally try to get an unsigned int
00257                 or some other type when we mean int (which is the most common case) */
00258         bool GetIntValue(const char *name, int &value) const
00259                 {return GetValue(name, value);}
00260 
00261         //! get a named value with type int, with default
00262         int GetIntValueWithDefault(const char *name, int defaultValue) const
00263                 {return GetValueWithDefault(name, defaultValue);}
00264 
00265         //! used by derived classes to check for type mismatch
00266         static void ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
00267                 {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);}
00268 
00269         template <class T>
00270         void GetRequiredParameter(const char *className, const char *name, T &value) const
00271         {
00272                 if (!GetValue(name, value))
00273                         throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
00274         }
00275 
00276         void GetRequiredIntParameter(const char *className, const char *name, int &value) const
00277         {
00278                 if (!GetIntValue(name, value))
00279                         throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'");
00280         }
00281 
00282         //! to be implemented by derived classes, users should use one of the above functions instead
00283         virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
00284 };
00285 
00286 //! namespace containing value name definitions
00287 /*!     value names, types and semantics:
00288 
00289         ThisObject:ClassName (ClassName, copy of this object or a subobject)
00290         ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject)
00291 */
00292 DOCUMENTED_NAMESPACE_BEGIN(Name)
00293 // more names defined in argnames.h
00294 DOCUMENTED_NAMESPACE_END
00295 
00296 //! .
00297 class NullNameValuePairs : public NameValuePairs
00298 {
00299 public:
00300         bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
00301 };
00302 
00303 //! .
00304 extern const NullNameValuePairs g_nullNameValuePairs;
00305 
00306 // ********************************************************
00307 
00308 //! interface for cloning objects, this is not implemented by most classes yet
00309 class Clonable
00310 {
00311 public:
00312         virtual ~Clonable() {}
00313         //! this is not implemented by most classes yet
00314         virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");}      // TODO: make this =0
00315 };
00316 
00317 //! interface for all crypto algorithms
00318 
00319 class Algorithm : public Clonable
00320 {
00321 public:
00322         /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true,
00323                 this constructor throws SelfTestFailure if the self test hasn't been run or fails. */
00324         Algorithm(bool checkSelfTestStatus = true);
00325         //! returns name of this algorithm, not universally implemented yet
00326         virtual std::string AlgorithmName() const {return "unknown";}
00327 };
00328 
00329 //! keying interface for crypto algorithms that take byte strings as keys
00330 
00331 class SimpleKeyingInterface
00332 {
00333 public:
00334         //! returns smallest valid key length in bytes */
00335         virtual unsigned int MinKeyLength() const =0;
00336         //! returns largest valid key length in bytes */
00337         virtual unsigned int MaxKeyLength() const =0;
00338         //! returns default (recommended) key length in bytes */
00339         virtual unsigned int DefaultKeyLength() const =0;
00340 
00341         //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength())
00342         virtual unsigned int GetValidKeyLength(unsigned int n) const =0;
00343 
00344         //! returns whether n is a valid key length
00345         virtual bool IsValidKeyLength(unsigned int n) const
00346                 {return n == GetValidKeyLength(n);}
00347 
00348         //! set or reset the key of this object
00349         /*! \param params is used to specify Rounds, BlockSize, etc */
00350         virtual void SetKey(const byte *key, unsigned int length, const NameValuePairs &params = g_nullNameValuePairs) =0;
00351 
00352         //! calls SetKey() with an NameValuePairs object that just specifies "Rounds"
00353         void SetKeyWithRounds(const byte *key, unsigned int length, int rounds);
00354 
00355         //! calls SetKey() with an NameValuePairs object that just specifies "IV"
00356         void SetKeyWithIV(const byte *key, unsigned int length, const byte *iv);
00357 
00358         enum IV_Requirement {STRUCTURED_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE};
00359         //! returns the minimal requirement for secure IVs
00360         virtual IV_Requirement IVRequirement() const =0;
00361 
00362         //! returns whether this object can be resynchronized (i.e. supports initialization vectors)
00363         /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */
00364         bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;}
00365         //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV)
00366         bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;}
00367         //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV)
00368         bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;}
00369         //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV)
00370         bool CanUseStructuredIVs() const {return IVRequirement() <= STRUCTURED_IV;}
00371 
00372         //! returns size of IVs used by this object
00373         virtual unsigned int IVSize() const {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00374         //! resynchronize with an IV
00375         virtual void Resynchronize(const byte *IV) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");}
00376         //! get a secure IV for the next message
00377         /*! This method should be called after you finish encrypting one message and are ready to start the next one.
00378                 After calling it, you must call SetKey() or Resynchronize() before using this object again. 
00379                 This method is not implemented on decryption objects. */
00380         virtual void GetNextIV(byte *IV) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support GetNextIV()");}
00381 
00382 protected:
00383         void ThrowIfInvalidKeyLength(const Algorithm &algorithm, unsigned int length);
00384 
00385         inline void AssertValidKeyLength(unsigned int length) const
00386         {
00387                 assert(IsValidKeyLength(length));
00388         }
00389 };
00390 
00391 //! interface for the data processing part of block ciphers
00392 
00393 /*! Classes derived from BlockTransformation are block ciphers
00394         in ECB mode (for example the DES::Encryption class), which are stateless,
00395         and they can make assumptions about the memory alignment of their inputs and outputs.
00396         These classes should not be used directly, but only in combination with
00397         a mode class (see CipherModeDocumentation in modes.h).
00398 */
00399 class BlockTransformation : public Algorithm
00400 {
00401 public:
00402         //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock
00403         virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0;
00404 
00405         //! encrypt or decrypt one block
00406         /*! \pre size of inBlock and outBlock == BlockSize() */
00407         void ProcessBlock(const byte *inBlock, byte *outBlock) const
00408                 {ProcessAndXorBlock(inBlock, NULL, outBlock);}
00409 
00410         //! encrypt or decrypt one block in place
00411         void ProcessBlock(byte *inoutBlock) const
00412                 {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);}
00413 
00414         //! block size of the cipher in bytes
00415         virtual unsigned int BlockSize() const =0;
00416 
00417         //! block pointers must be divisible by this
00418         virtual unsigned int BlockAlignment() const {return 4;}
00419 
00420         //! returns true if this is a permutation (i.e. there is an inverse transformation)
00421         virtual bool IsPermutation() const {return true;}
00422 
00423         //! returns true if this is an encryption object
00424         virtual bool IsForwardTransformation() const =0;
00425 
00426         //! return number of blocks that can be processed in parallel, for bit-slicing implementations
00427         virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;}
00428 
00429         //! encrypt or decrypt multiple blocks, for bit-slicing implementations
00430         virtual void ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, unsigned int numberOfBlocks) const;
00431 };
00432 
00433 //! interface for the data processing part of stream ciphers
00434 
00435 class StreamTransformation : public Algorithm
00436 {
00437 public:
00438         //! return a reference to this object, 
00439         /*! This function is useful for passing a temporary StreamTransformation object to a 
00440                 function that takes a non-const reference. */
00441         StreamTransformation& Ref() {return *this;}
00442 
00443         //! returns block size, if input must be processed in blocks, otherwise 1
00444         virtual unsigned int MandatoryBlockSize() const {return 1;}
00445 
00446         //! returns the input block size that is most efficient for this cipher
00447         /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */
00448         virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();}
00449         //! returns how much of the current block is used up
00450         virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;}
00451 
00452         //! returns how input should be aligned for optimal performance
00453         virtual unsigned int OptimalDataAlignment() const {return 1;}
00454 
00455         //! encrypt or decrypt an array of bytes of specified length
00456         /*! \note either inString == outString, or they don't overlap */
00457         virtual void ProcessData(byte *outString, const byte *inString, unsigned int length) =0;
00458 
00459         //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data
00460         /*! For now the only use of this function is for CBC-CTS mode. */
00461         virtual void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
00462         //! returns the minimum size of the last block, 0 indicating the last block is not special
00463         virtual unsigned int MinLastBlockSize() const {return 0;}
00464 
00465         //! same as ProcessData(inoutString, inoutString, length)
00466         inline void ProcessString(byte *inoutString, unsigned int length)
00467                 {ProcessData(inoutString, inoutString, length);}
00468         //! same as ProcessData(outString, inString, length)
00469         inline void ProcessString(byte *outString, const byte *inString, unsigned int length)
00470                 {ProcessData(outString, inString, length);}
00471         //! implemented as {ProcessData(&input, &input, 1); return input;}
00472         inline byte ProcessByte(byte input)
00473                 {ProcessData(&input, &input, 1); return input;}
00474 
00475         //! returns whether this cipher supports random access
00476         virtual bool IsRandomAccess() const =0;
00477         //! for random access ciphers, seek to an absolute position
00478         virtual void Seek(dword n)
00479         {
00480                 assert(!IsRandomAccess());
00481                 throw NotImplemented("StreamTransformation: this object doesn't support random access");
00482         }
00483 
00484         //! returns whether this transformation is self-inverting (e.g. xor with a keystream)
00485         virtual bool IsSelfInverting() const =0;
00486         //! returns whether this is an encryption object
00487         virtual bool IsForwardTransformation() const =0;
00488 };
00489 
00490 //! interface for hash functions and data processing part of MACs
00491 
00492 /*! HashTransformation objects are stateful.  They are created in an initial state,
00493         change state as Update() is called, and return to the initial
00494         state when Final() is called.  This interface allows a large message to
00495         be hashed in pieces by calling Update() on each piece followed by
00496         calling Final().
00497 */
00498 class HashTransformation : public Algorithm
00499 {
00500 public:
00501         //! process more input
00502         virtual void Update(const byte *input, unsigned int length) =0;
00503 
00504         //! request space to write input into
00505         virtual byte * CreateUpdateSpace(unsigned int &size) {size=0; return NULL;}
00506 
00507         //! compute hash for current message, then restart for a new message
00508         /*!     \pre size of digest == DigestSize(). */
00509         virtual void Final(byte *digest)
00510                 {TruncatedFinal(digest, DigestSize());}
00511 
00512         //! discard the current state, and restart with a new message
00513         virtual void Restart()
00514                 {TruncatedFinal(NULL, 0);}
00515 
00516         //! size of the hash returned by Final()
00517         virtual unsigned int DigestSize() const =0;
00518 
00519         //! input to Update() should have length a multiple of this for optimal speed
00520         virtual unsigned int OptimalBlockSize() const {return 1;}
00521 
00522         //! returns how input should be aligned for optimal performance
00523         virtual unsigned int OptimalDataAlignment() const {return 1;}
00524 
00525         //! use this if your input is in one piece and you don't want to call Update() and Final() separately
00526         virtual void CalculateDigest(byte *digest, const byte *input, unsigned int length)
00527                 {Update(input, length); Final(digest);}
00528 
00529         //! verify that digest is a valid digest for the current message, then reinitialize the object
00530         /*! Default implementation is to call Final() and do a bitwise comparison
00531                 between its output and digest. */
00532         virtual bool Verify(const byte *digest)
00533                 {return TruncatedVerify(digest, DigestSize());}
00534 
00535         //! use this if your input is in one piece and you don't want to call Update() and Verify() separately
00536         virtual bool VerifyDigest(const byte *digest, const byte *input, unsigned int length)
00537                 {Update(input, length); return Verify(digest);}
00538 
00539         //! truncated version of Final()
00540         virtual void TruncatedFinal(byte *digest, unsigned int digestSize) =0;
00541 
00542         //! truncated version of CalculateDigest()
00543         virtual void CalculateTruncatedDigest(byte *digest, unsigned int digestSize, const byte *input, unsigned int length)
00544                 {Update(input, length); TruncatedFinal(digest, digestSize);}
00545 
00546         //! truncated version of Verify()
00547         virtual bool TruncatedVerify(const byte *digest, unsigned int digestLength);
00548 
00549         //! truncated version of VerifyDigest()
00550         virtual bool VerifyTruncatedDigest(const byte *digest, unsigned int digestLength, const byte *input, unsigned int length)
00551                 {Update(input, length); return TruncatedVerify(digest, digestLength);}
00552 
00553 protected:
00554         void ThrowIfInvalidTruncatedSize(unsigned int size) const;
00555 };
00556 
00557 //! .
00558 template <class T>
00559 class SimpleKeyedTransformation : public T, public SimpleKeyingInterface
00560 {
00561 public:
00562         void ThrowIfInvalidKeyLength(unsigned int length)
00563                 {SimpleKeyingInterface::ThrowIfInvalidKeyLength(*this, length);}
00564 };
00565 
00566 //! .
00567 typedef HashTransformation HashFunction;
00568 #ifdef CRYPTOPP_DOXYGEN_PROCESSING
00569 //! These objects usually should not be used directly. See BlockTransformation for more details.
00570 class BlockCipher : public BlockTransformation, public SimpleKeyingInterface {};
00571 //! interface for stream ciphers
00572 class SymmetricCipher : public StreamTransformation, public SimpleKeyingInterface {};
00573 //! interface for message authentication codes
00574 class MessageAuthenticationCode : public HashTransformation, public SimpleKeyingInterface {};
00575 #else
00576 typedef SimpleKeyedTransformation<BlockTransformation> BlockCipher;
00577 typedef SimpleKeyedTransformation<StreamTransformation> SymmetricCipher;
00578 typedef SimpleKeyedTransformation<HashTransformation> MessageAuthenticationCode;
00579 #endif
00580 
00581 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00582 typedef SymmetricCipher StreamCipher;
00583 #endif
00584 
00585 //! interface for random number generators
00586 /*! All return values are uniformly distributed over the range specified.
00587 */
00588 class RandomNumberGenerator : public Algorithm
00589 {
00590 public:
00591         //! generate new random byte and return it
00592         virtual byte GenerateByte() =0;
00593 
00594         //! generate new random bit and return it
00595         /*! Default implementation is to call GenerateByte() and return its parity. */
00596         virtual unsigned int GenerateBit();
00597 
00598         //! generate a random 32 bit word in the range min to max, inclusive
00599         virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL);
00600 
00601         //! generate random array of bytes
00602         /*! Default implementation is to call GenerateByte() size times. */
00603         virtual void GenerateBlock(byte *output, unsigned int size);
00604 
00605         //! generate and discard n bytes
00606         /*! Default implementation is to call GenerateByte() n times. */
00607         virtual void DiscardBytes(unsigned int n);
00608 
00609         //! randomly shuffle the specified array, resulting permutation is uniformly distributed
00610         template <class IT> void Shuffle(IT begin, IT end)
00611         {
00612                 for (; begin != end; ++begin)
00613                         std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1));
00614         }
00615 
00616 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00617         byte GetByte() {return GenerateByte();}
00618         unsigned int GetBit() {return GenerateBit();}
00619         word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);}
00620         word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);}
00621         void GetBlock(byte *output, unsigned int size) {GenerateBlock(output, size);}
00622 #endif
00623 };
00624 
00625 //! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it
00626 RandomNumberGenerator & NullRNG();
00627 
00628 class WaitObjectContainer;
00629 
00630 //! interface for objects that you can wait for
00631 
00632 class Waitable
00633 {
00634 public:
00635         //! maximum number of wait objects that this object can return
00636         virtual unsigned int GetMaxWaitObjectCount() const =0;
00637         //! put wait objects into container
00638         virtual void GetWaitObjects(WaitObjectContainer &container) =0;
00639         //! wait on this object
00640         /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */
00641         bool Wait(unsigned long milliseconds);
00642 };
00643 
00644 //! interface for buffered transformations
00645 
00646 /*! BufferedTransformation is a generalization of BlockTransformation,
00647         StreamTransformation, and HashTransformation.
00648 
00649         A buffered transformation is an object that takes a stream of bytes
00650         as input (this may be done in stages), does some computation on them, and
00651         then places the result into an internal buffer for later retrieval.  Any
00652         partial result already in the output buffer is not modified by further
00653         input.
00654 
00655         If a method takes a "blocking" parameter, and you
00656         pass "false" for it, the method will return before all input has been processed if
00657         the input cannot be processed without waiting (for network buffers to become available, for example).
00658         In this case the method will return true
00659         or a non-zero integer value. When this happens you must continue to call the method with the same
00660         parameters until it returns false or zero, before calling any other method on it or
00661         attached BufferedTransformation. The integer return value in this case is approximately
00662         the number of bytes left to be processed, and can be used to implement a progress bar.
00663 
00664         For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached
00665         BufferedTransformation objects, with propagation decremented at each step until it reaches 0.
00666         -1 means unlimited propagation.
00667 
00668         \nosubgrouping
00669 */
00670 class BufferedTransformation : public Algorithm, public Waitable
00671 {
00672 public:
00673         // placed up here for CW8
00674         static const std::string NULL_CHANNEL;  // the empty string ""
00675 
00676         BufferedTransformation() : Algorithm(false) {}
00677 
00678         //! return a reference to this object
00679         /*! This function is useful for passing a temporary BufferedTransformation object to a 
00680                 function that takes a non-const reference. */
00681         BufferedTransformation& Ref() {return *this;}
00682 
00683         //!     \name INPUT
00684         //@{
00685                 //! input a byte for processing
00686                 unsigned int Put(byte inByte, bool blocking=true)
00687                         {return Put(&inByte, 1, blocking);}
00688                 //! input multiple bytes
00689                 unsigned int Put(const byte *inString, unsigned int length, bool blocking=true)
00690                         {return Put2(inString, length, 0, blocking);}
00691 
00692                 //! input a 16-bit word
00693                 unsigned int PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00694                 //! input a 32-bit word
00695                 unsigned int PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00696 
00697                 //! request space which can be written into by the caller, and then used as input to Put()
00698                 /*! \param size is requested size (as a hint) for input, and size of the returned space for output */
00699                 /*! \note The purpose of this method is to help avoid doing extra memory allocations. */
00700                 virtual byte * CreatePutSpace(unsigned int &size) {size=0; return NULL;}
00701 
00702                 virtual bool CanModifyInput() const {return false;}
00703 
00704                 //! input multiple bytes that may be modified by callee
00705                 unsigned int PutModifiable(byte *inString, unsigned int length, bool blocking=true)
00706                         {return PutModifiable2(inString, length, 0, blocking);}
00707 
00708                 bool MessageEnd(int propagation=-1, bool blocking=true)
00709                         {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
00710                 unsigned int PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1, bool blocking=true)
00711                         {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
00712 
00713                 //! input multiple bytes for blocking or non-blocking processing
00714                 /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
00715                 virtual unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking) =0;
00716                 //! input multiple bytes that may be modified by callee for blocking or non-blocking processing
00717                 /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */
00718                 virtual unsigned int PutModifiable2(byte *inString, unsigned int length, int messageEnd, bool blocking)
00719                         {return Put2(inString, length, messageEnd, blocking);}
00720 
00721                 //! thrown by objects that have not implemented nonblocking input processing
00722                 struct BlockingInputOnly : public NotImplemented
00723                         {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}};
00724         //@}
00725 
00726         //!     \name WAITING
00727         //@{
00728                 unsigned int GetMaxWaitObjectCount() const;
00729                 void GetWaitObjects(WaitObjectContainer &container);
00730         //@}
00731 
00732         //!     \name SIGNALS
00733         //@{
00734                 virtual void IsolatedInitialize(const NameValuePairs &parameters) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");}
00735                 virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0;
00736                 virtual bool IsolatedMessageSeriesEnd(bool blocking) {return false;}
00737 
00738                 //! initialize or reinitialize this object
00739                 virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
00740                 //! flush buffered input and/or output
00741                 /*! \param hardFlush is used to indicate whether all data should be flushed
00742                         \note Hard flushes must be used with care. It means try to process and output everything, even if
00743                         there may not be enough data to complete the action. For example, hard flushing a HexDecoder would
00744                         cause an error if you do it after inputing an odd number of hex encoded characters.
00745                         For some types of filters, for example ZlibDecompressor, hard flushes can only
00746                         be done at "synchronization points". These synchronization points are positions in the data
00747                         stream that are created by hard flushes on the corresponding reverse filters, in this
00748                         example ZlibCompressor. This is useful when zlib compressed data is moved across a
00749                         network in packets and compression state is preserved across packets, as in the ssh2 protocol.
00750                 */
00751                 virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
00752                 //! mark end of a series of messages
00753                 /*! There should be a MessageEnd immediately before MessageSeriesEnd. */
00754                 virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
00755 
00756                 //! set propagation of automatically generated and transfered signals
00757                 /*! propagation == 0 means do not automaticly generate signals */
00758                 virtual void SetAutoSignalPropagation(int propagation) {}
00759 
00760                 //!
00761                 virtual int GetAutoSignalPropagation() const {return 0;}
00762 public:
00763 
00764 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00765                 void Close() {MessageEnd();}
00766 #endif
00767         //@}
00768 
00769         //!     \name RETRIEVAL OF ONE MESSAGE
00770         //@{
00771                 //! returns number of bytes that is currently ready for retrieval
00772                 /*! All retrieval functions return the actual number of bytes
00773                         retrieved, which is the lesser of the request number and
00774                         MaxRetrievable(). */
00775                 virtual unsigned long MaxRetrievable() const;
00776 
00777                 //! returns whether any bytes are currently ready for retrieval
00778                 virtual bool AnyRetrievable() const;
00779 
00780                 //! try to retrieve a single byte
00781                 virtual unsigned int Get(byte &outByte);
00782                 //! try to retrieve multiple bytes
00783                 virtual unsigned int Get(byte *outString, unsigned int getMax);
00784 
00785                 //! peek at the next byte without removing it from the output buffer
00786                 virtual unsigned int Peek(byte &outByte) const;
00787                 //! peek at multiple bytes without removing them from the output buffer
00788                 virtual unsigned int Peek(byte *outString, unsigned int peekMax) const;
00789 
00790                 //! try to retrieve a 16-bit word
00791                 unsigned int GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);
00792                 //! try to retrieve a 32-bit word
00793                 unsigned int GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
00794 
00795                 //! try to peek at a 16-bit word
00796                 unsigned int PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);
00797                 //! try to peek at a 32-bit word
00798                 unsigned int PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
00799 
00800                 //! move transferMax bytes of the buffered output to target as input
00801                 unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL)
00802                         {TransferTo2(target, transferMax, channel); return transferMax;}
00803 
00804                 //! discard skipMax bytes from the output buffer
00805                 virtual unsigned long Skip(unsigned long skipMax=ULONG_MAX);
00806 
00807                 //! copy copyMax bytes of the buffered output to target as input
00808                 unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL) const
00809                         {return CopyRangeTo(target, 0, copyMax, channel);}
00810 
00811                 //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input
00812                 unsigned long CopyRangeTo(BufferedTransformation &target, unsigned long position, unsigned long copyMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL) const
00813                         {unsigned long i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;}
00814 
00815 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00816                 unsigned long MaxRetrieveable() const {return MaxRetrievable();}
00817 #endif
00818         //@}
00819 
00820         //!     \name RETRIEVAL OF MULTIPLE MESSAGES
00821         //@{
00822                 //!
00823                 virtual unsigned long TotalBytesRetrievable() const;
00824                 //! number of times MessageEnd() has been received minus messages retrieved or skipped
00825                 virtual unsigned int NumberOfMessages() const;
00826                 //! returns true if NumberOfMessages() > 0
00827                 virtual bool AnyMessages() const;
00828                 //! start retrieving the next message
00829                 /*!
00830                         Returns false if no more messages exist or this message 
00831                         is not completely retrieved.
00832                 */
00833                 virtual bool GetNextMessage();
00834                 //! skip count number of messages
00835                 virtual unsigned int SkipMessages(unsigned int count=UINT_MAX);
00836                 //!
00837                 unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL)
00838                         {TransferMessagesTo2(target, count, channel); return count;}
00839                 //!
00840                 unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const;
00841 
00842                 //!
00843                 virtual void SkipAll();
00844                 //!
00845                 void TransferAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL)
00846                         {TransferAllTo2(target, channel);}
00847                 //!
00848                 void CopyAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL) const;
00849 
00850                 virtual bool GetNextMessageSeries() {return false;}
00851                 virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();}
00852                 virtual unsigned int NumberOfMessageSeries() const {return 0;}
00853         //@}
00854 
00855         //!     \name NON-BLOCKING TRANSFER OF OUTPUT
00856         //@{
00857                 //! .
00858                 virtual unsigned int TransferTo2(BufferedTransformation &target, unsigned long &byteCount, const std::string &channel=NULL_CHANNEL, bool blocking=true) =0;
00859                 virtual unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const =0;
00860                 unsigned int TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00861                 unsigned int TransferAllTo2(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00862         //@}
00863 
00864         //!     \name CHANNELS
00865         //@{
00866                 struct NoChannelSupport : public NotImplemented
00867                         {NoChannelSupport() : NotImplemented("BufferedTransformation: this object doesn't support multiple channels") {}};
00868 
00869                 unsigned int ChannelPut(const std::string &channel, byte inByte, bool blocking=true)
00870                         {return ChannelPut(channel, &inByte, 1, blocking);}
00871                 unsigned int ChannelPut(const std::string &channel, const byte *inString, unsigned int length, bool blocking=true)
00872                         {return ChannelPut2(channel, inString, length, 0, blocking);}
00873 
00874                 unsigned int ChannelPutModifiable(const std::string &channel, byte *inString, unsigned int length, bool blocking=true)
00875                         {return ChannelPutModifiable2(channel, inString, length, 0, blocking);}
00876 
00877                 unsigned int ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00878                 unsigned int ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
00879 
00880                 bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00881                         {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);}
00882                 unsigned int ChannelPutMessageEnd(const std::string &channel, const byte *inString, unsigned int length, int propagation=-1, bool blocking=true)
00883                         {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);}
00884 
00885                 virtual byte * ChannelCreatePutSpace(const std::string &channel, unsigned int &size);
00886 
00887                 virtual unsigned int ChannelPut2(const std::string &channel, const byte *begin, unsigned int length, int messageEnd, bool blocking);
00888                 virtual unsigned int ChannelPutModifiable2(const std::string &channel, byte *begin, unsigned int length, int messageEnd, bool blocking);
00889 
00890                 virtual void ChannelInitialize(const std::string &channel, const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
00891                 virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true);
00892                 virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true);
00893 
00894                 virtual void SetRetrievalChannel(const std::string &channel);
00895         //@}
00896 
00897         //!     \name ATTACHMENT
00898         /*! Some BufferedTransformation objects (e.g. Filter objects)
00899                 allow other BufferedTransformation objects to be attached. When
00900                 this is done, the first object instead of buffering its output,
00901                 sents that output to the attached object as input. The entire
00902                 attachment chain is deleted when the anchor object is destructed.
00903         */
00904         //@{
00905                 //! returns whether this object allows attachment
00906                 virtual bool Attachable() {return false;}
00907                 //! returns the object immediately attached to this object or NULL for no attachment
00908                 virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;}
00909                 //!
00910                 virtual const BufferedTransformation *AttachedTransformation() const
00911                         {return const_cast<BufferedTransformation *>(this)->AttachedTransformation();}
00912                 //! delete the current attachment chain and replace it with newAttachment
00913                 virtual void Detach(BufferedTransformation *newAttachment = 0)
00914                         {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");}
00915                 //! add newAttachment to the end of attachment chain
00916                 virtual void Attach(BufferedTransformation *newAttachment);
00917         //@}
00918 
00919 protected:
00920         static int DecrementPropagation(int propagation)
00921                 {return propagation != 0 ? propagation - 1 : 0;}
00922 };
00923 
00924 //! returns a reference to a BufferedTransformation object that discards all input
00925 BufferedTransformation & TheBitBucket();
00926 
00927 //! interface for crypto material, such as public and private keys, and crypto parameters
00928 
00929 class CryptoMaterial : public NameValuePairs
00930 {
00931 public:
00932         //! exception thrown when invalid crypto material is detected
00933         class InvalidMaterial : public InvalidDataFormat
00934         {
00935         public:
00936                 explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {}
00937         };
00938 
00939         //! assign values from source to this object
00940         /*! \note This function can be used to create a public key from a private key. */
00941         virtual void AssignFrom(const NameValuePairs &source) =0;
00942 
00943         //! check this object for errors
00944         /*! \param level denotes the level of thoroughness:
00945                 0 - using this object won't cause a crash or exception (rng is ignored)
00946                 1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such)
00947                 2 - make sure this object will function correctly, and do reasonable security checks
00948                 3 - do checks that may take a long time
00949                 \return true if the tests pass */
00950         virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0;
00951 
00952         //! throws InvalidMaterial if this object fails Validate() test
00953         virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
00954                 {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}
00955 
00956 //      virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false);
00957 
00958         //! save key into a BufferedTransformation
00959         virtual void Save(BufferedTransformation &bt) const
00960                 {throw NotImplemented("CryptoMaterial: this object does not support saving");}
00961 
00962         //! load key from a BufferedTransformation
00963         /*! \throws KeyingErr if decode fails
00964                 \note Generally does not check that the key is valid.
00965                         Call ValidateKey() or ThrowIfInvalidKey() to check that. */
00966         virtual void Load(BufferedTransformation &bt)
00967                 {throw NotImplemented("CryptoMaterial: this object does not support loading");}
00968 
00969         //! \return whether this object supports precomputation
00970         virtual bool SupportsPrecomputation() const {return false;}
00971         //! do precomputation
00972         /*! The exact semantics of Precompute() is varies, but
00973                 typically it means calculate a table of n objects
00974                 that can be used later to speed up computation. */
00975         virtual void Precompute(unsigned int n)
00976                 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
00977         //! retrieve previously saved precomputation
00978         virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation)
00979                 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
00980         //! save precomputation for later use
00981         virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
00982                 {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
00983 
00984         // for internal library use
00985         void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);}
00986 };
00987 
00988 //! interface for generatable crypto material, such as private keys and crypto parameters
00989 
00990 class GeneratableCryptoMaterial : virtual public CryptoMaterial
00991 {
00992 public:
00993         //! generate a random key or crypto parameters
00994         /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated
00995                 (e.g., if this is a public key object) */
00996         virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params = g_nullNameValuePairs)
00997                 {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");}
00998 
00999         //! calls the above function with a NameValuePairs object that just specifies "KeySize"
01000         void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize);
01001 };
01002 
01003 //! interface for public keys
01004 
01005 class PublicKey : virtual public CryptoMaterial
01006 {
01007 };
01008 
01009 //! interface for private keys
01010 
01011 class PrivateKey : public GeneratableCryptoMaterial
01012 {
01013 };
01014 
01015 //! interface for crypto prameters
01016 
01017 class CryptoParameters : public GeneratableCryptoMaterial
01018 {
01019 };
01020 
01021 //! interface for asymmetric algorithms
01022 
01023 class AsymmetricAlgorithm : public Algorithm
01024 {
01025 public:
01026         //! returns a reference to the crypto material used by this object
01027         virtual CryptoMaterial & AccessMaterial() =0;
01028         //! returns a const reference to the crypto material used by this object
01029         virtual const CryptoMaterial & GetMaterial() const =0;
01030 
01031         //! for backwards compatibility, calls AccessMaterial().Load(bt)
01032         void BERDecode(BufferedTransformation &bt)
01033                 {AccessMaterial().Load(bt);}
01034         //! for backwards compatibility, calls GetMaterial().Save(bt)
01035         void DEREncode(BufferedTransformation &bt) const
01036                 {GetMaterial().Save(bt);}
01037 };
01038 
01039 //! interface for asymmetric algorithms using public keys
01040 
01041 class PublicKeyAlgorithm : public AsymmetricAlgorithm
01042 {
01043 public:
01044         // VC60 workaround: no co-variant return type
01045         CryptoMaterial & AccessMaterial() {return AccessPublicKey();}
01046         const CryptoMaterial & GetMaterial() const {return GetPublicKey();}
01047 
01048         virtual PublicKey & AccessPublicKey() =0;
01049         virtual const PublicKey & GetPublicKey() const {return const_cast<PublicKeyAlgorithm *>(this)->AccessPublicKey();}
01050 };
01051 
01052 //! interface for asymmetric algorithms using private keys
01053 
01054 class PrivateKeyAlgorithm : public AsymmetricAlgorithm
01055 {
01056 public:
01057         CryptoMaterial & AccessMaterial() {return AccessPrivateKey();}
01058         const CryptoMaterial & GetMaterial() const {return GetPrivateKey();}
01059 
01060         virtual PrivateKey & AccessPrivateKey() =0;
01061         virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();}
01062 };
01063 
01064 //! interface for key agreement algorithms
01065 
01066 class KeyAgreementAlgorithm : public AsymmetricAlgorithm
01067 {
01068 public:
01069         CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();}
01070         const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();}
01071 
01072         virtual CryptoParameters & AccessCryptoParameters() =0;
01073         virtual const CryptoParameters & GetCryptoParameters() const {return const_cast<KeyAgreementAlgorithm *>(this)->AccessCryptoParameters();}
01074 };
01075 
01076 //! interface for public-key encryptors and decryptors
01077 
01078 /*! This class provides an interface common to encryptors and decryptors
01079         for querying their plaintext and ciphertext lengths.
01080 */
01081 class PK_CryptoSystem
01082 {
01083 public:
01084         virtual ~PK_CryptoSystem() {}
01085 
01086         //! maximum length of plaintext for a given ciphertext length
01087         /*! \note This function returns 0 if cipherTextLength is not valid (too long or too short). */
01088         virtual unsigned int MaxPlaintextLength(unsigned int cipherTextLength) const =0;
01089 
01090         //! calculate length of ciphertext given length of plaintext
01091         /*! \note This function returns 0 if plainTextLength is not valid (too long). */
01092         virtual unsigned int CiphertextLength(unsigned int plainTextLength) const =0;
01093 
01094 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01095         unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);}
01096         unsigned int CipherTextLength(unsigned int plainTextLength) const {return CiphertextLength(plainTextLength);}
01097 #endif
01098 };
01099 
01100 //! interface for public-key encryptors
01101 
01102 class PK_Encryptor : virtual public PK_CryptoSystem, public PublicKeyAlgorithm
01103 {
01104 public:
01105         //! .
01106         class InvalidPlaintextLength : public Exception
01107         {
01108         public:
01109                 InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {}
01110         };
01111 
01112         //! encrypt a byte string
01113         /*! \pre CipherTextLength(plainTextLength) != 0 (i.e., plainText isn't too long)
01114                 \pre size of cipherText == CipherTextLength(plainTextLength)
01115         */
01116         virtual void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const =0;
01117 
01118         //! create a new encryption filter
01119         /*! \note caller is responsible for deleting the returned pointer
01120         */
01121         virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL) const;
01122 };
01123 
01124 //! interface for public-key decryptors
01125 
01126 class PK_Decryptor : virtual public PK_CryptoSystem, public PrivateKeyAlgorithm
01127 {
01128 public:
01129         //! decrypt a byte string, and return the length of plaintext
01130         /*! \pre size of plainText == MaxPlainTextLength(cipherTextLength) bytes.
01131                 \return the actual length of the plaintext, or 0 if decryption fails.
01132         */
01133         virtual DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const =0;
01134 
01135         //! create a new decryption filter
01136         /*! \note caller is responsible for deleting the returned pointer
01137         */
01138         virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL) const;
01139 };
01140 
01141 //! interface for encryptors and decryptors with fixed length ciphertext
01142 
01143 /*! A simplified interface is provided for crypto systems (such
01144         as RSA) whose ciphertext length and maximum plaintext length
01145         depend only on the key.
01146 */
01147 class PK_FixedLengthCryptoSystem : virtual public PK_CryptoSystem
01148 {
01149 public:
01150         //!
01151         virtual unsigned int FixedMaxPlaintextLength() const =0;
01152         //!
01153         virtual unsigned int FixedCiphertextLength() const =0;
01154 
01155         unsigned int MaxPlaintextLength(unsigned int cipherTextLength) const;
01156         unsigned int CiphertextLength(unsigned int plainTextLength) const;
01157         
01158 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01159         unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);}
01160         unsigned int CipherTextLength(unsigned int plainTextLength) const {return CiphertextLength(plainTextLength);}
01161         unsigned int MaxPlainTextLength() const {return FixedMaxPlaintextLength();}
01162         unsigned int CipherTextLength() const {return FixedCiphertextLength();}
01163 #endif
01164 };
01165 
01166 //! interface for encryptors with fixed length ciphertext
01167 
01168 class PK_FixedLengthEncryptor : public PK_Encryptor, virtual public PK_FixedLengthCryptoSystem
01169 {
01170 };
01171 
01172 //! interface for decryptors with fixed length ciphertext
01173 
01174 class PK_FixedLengthDecryptor : public PK_Decryptor, virtual public PK_FixedLengthCryptoSystem
01175 {
01176 public:
01177         //! decrypt a byte string, and return the length of plaintext
01178         /*! \pre length of cipherText == CipherTextLength()
01179                 \pre size of plainText == MaxPlainTextLength()
01180                 \return the actual length of the plaintext, or 0 if decryption fails.
01181         */
01182         virtual DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const =0;
01183 
01184         DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const;
01185 };
01186 
01187 //! interface for public-key signers and verifiers
01188 
01189 /*! This class provides an interface common to signers and verifiers
01190         for querying scheme properties.
01191 */
01192 class PK_SignatureScheme
01193 {
01194 public:
01195         //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used
01196         class InvalidKeyLength : public Exception
01197         {
01198         public:
01199                 InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {}
01200         };
01201 
01202         //! key too short exception, may be thrown by any function in this class if the private or public key is too short to sign or verify anything
01203         class KeyTooShort : public InvalidKeyLength
01204         {
01205         public:
01206                 KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {}
01207         };
01208 
01209         virtual ~PK_SignatureScheme() {}
01210 
01211         //! signature length if it only depends on the key, otherwise 0
01212         virtual unsigned int SignatureLength() const =0;
01213 
01214         //! maximum signature length produced for a given length of recoverable message part
01215         virtual unsigned int MaxSignatureLength(unsigned int recoverablePartLength = 0) const {return SignatureLength();}
01216 
01217         //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery
01218         virtual unsigned int MaxRecoverableLength() const =0;
01219 
01220         //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery
01221         virtual unsigned int MaxRecoverableLengthFromSignatureLength(unsigned int signatureLength) const =0;
01222 
01223         //! requires a random number generator to sign
01224         /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */
01225         virtual bool IsProbabilistic() const =0;
01226 
01227         //! whether or not a non-recoverable message part can be signed
01228         virtual bool AllowNonrecoverablePart() const =0;
01229 
01230         //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */
01231         virtual bool SignatureUpfront() const {return false;}
01232 
01233         //! whether you must input the recoverable part before the non-recoverable part during signing
01234         virtual bool RecoverablePartFirst() const =0;
01235 };
01236 
01237 //! interface for accumulating messages to be signed or verified
01238 /*! Only Update() should be called
01239         on this class. No other functions inherited from HashTransformation should be called.
01240 */
01241 class PK_MessageAccumulator : public HashTransformation
01242 {
01243 public:
01244         //! should not be called on PK_MessageAccumulator
01245         unsigned int DigestSize() const
01246                 {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");}
01247         //! should not be called on PK_MessageAccumulator
01248         void TruncatedFinal(byte *digest, unsigned int digestSize) 
01249                 {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");}
01250 };
01251 
01252 //! interface for public-key signers
01253 
01254 class PK_Signer : virtual public PK_SignatureScheme, public PrivateKeyAlgorithm
01255 {
01256 public:
01257         //! create a new HashTransformation to accumulate the message to be signed
01258         virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng = NullRNG()) const =0;
01259 
01260         virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, unsigned int recoverableMessageLength) const =0;
01261 
01262         //! sign and delete messageAccumulator (even in case of exception thrown)
01263         /*! \pre size of signature == MaxSignatureLength()
01264                 \return actual signature length
01265         */
01266         virtual unsigned int Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const;
01267 
01268         //! sign and restart messageAccumulator
01269         /*! \pre size of signature == MaxSignatureLength()
01270                 \return actual signature length
01271         */
01272         virtual unsigned int SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0;
01273 
01274         //! sign a message
01275         /*! \pre size of signature == MaxSignatureLength()
01276                 \return actual signature length
01277         */
01278         virtual unsigned int SignMessage(RandomNumberGenerator &rng, const byte *message, unsigned int messageLen, byte *signature) const;
01279 
01280         //! sign a recoverable message
01281         /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength)
01282                 \return actual signature length
01283         */
01284         virtual unsigned int SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, unsigned int recoverableMessageLength, 
01285                 const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength, byte *signature) const;
01286 };
01287 
01288 //! interface for public-key signature verifiers
01289 /*! The Recover* functions throw NotImplemented if the signature scheme does not support
01290         message recovery.
01291         The Verify* functions throw InvalidDataFormat if the scheme does support message
01292         recovery and the signature contains a non-empty recoverable message part. The
01293         Recovery* functions should be used in that case.
01294 */
01295 class PK_Verifier : virtual public PK_SignatureScheme, public PublicKeyAlgorithm
01296 {
01297 public:
01298         //! create a new HashTransformation to accumulate the message to be verified
01299         virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0;
01300 
01301         //! input signature into a message accumulator
01302         virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const =0;
01303 
01304         //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown)
01305         virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const;
01306 
01307         //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator
01308         virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0;
01309 
01310         //! check whether input signature is a valid signature for input message
01311         virtual bool VerifyMessage(const byte *message, unsigned int messageLen, 
01312                 const byte *signature, unsigned int signatureLength) const;
01313 
01314         //! recover a message from its signature
01315         /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01316         */
01317         virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const;
01318 
01319         //! recover a message from its signature
01320         /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01321         */
01322         virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0;
01323 
01324         //! recover a message from its signature
01325         /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)
01326         */
01327         virtual DecodingResult RecoverMessage(byte *recoveredMessage, 
01328                 const byte *nonrecoverableMessage, unsigned int nonrecoverableMessageLength, 
01329                 const byte *signature, unsigned int signatureLength) const;
01330 };
01331 
01332 //! interface for domains of simple key agreement protocols
01333 
01334 /*! A key agreement domain is a set of parameters that must be shared
01335         by two parties in a key agreement protocol, along with the algorithms
01336         for generating key pairs and deriving agreed values.
01337 */
01338 class SimpleKeyAgreementDomain : public KeyAgreementAlgorithm
01339 {
01340 public:
01341         //! return length of agreed value produced
01342         virtual unsigned int AgreedValueLength() const =0;
01343         //! return length of private keys in this domain
01344         virtual unsigned int PrivateKeyLength() const =0;
01345         //! return length of public keys in this domain
01346         virtual unsigned int PublicKeyLength() const =0;
01347         //! generate private key
01348         /*! \pre size of privateKey == PrivateKeyLength() */
01349         virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
01350         //! generate public key
01351         /*!     \pre size of publicKey == PublicKeyLength() */
01352         virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
01353         //! generate private/public key pair
01354         /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */
01355         virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
01356         //! derive agreed value from your private key and couterparty's public key, return false in case of failure
01357         //! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time.
01358         /*! \pre size of agreedValue == AgreedValueLength()
01359                 \pre length of privateKey == PrivateKeyLength()
01360                 \pre length of otherPublicKey == PublicKeyLength()
01361         */
01362         virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0;
01363 
01364 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01365         bool ValidateDomainParameters(RandomNumberGenerator &rng) const
01366                 {return GetCryptoParameters().Validate(rng, 2);}
01367 #endif
01368 };
01369 
01370 //! interface for domains of authenticated key agreement protocols
01371 
01372 /*! In an authenticated key agreement protocol, each party has two
01373         key pairs. The long-lived key pair is called the static key pair,
01374         and the short-lived key pair is called the ephemeral key pair.
01375 */
01376 class AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
01377 {
01378 public:
01379         //! return length of agreed value produced
01380         virtual unsigned int AgreedValueLength() const =0;
01381 
01382         //! return length of static private keys in this domain
01383         virtual unsigned int StaticPrivateKeyLength() const =0;
01384         //! return length of static public keys in this domain
01385         virtual unsigned int StaticPublicKeyLength() const =0;
01386         //! generate static private key
01387         /*! \pre size of privateKey == PrivateStaticKeyLength() */
01388         virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
01389         //! generate static public key
01390         /*!     \pre size of publicKey == PublicStaticKeyLength() */
01391         virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
01392         //! generate private/public key pair
01393         /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */
01394         virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
01395 
01396         //! return length of ephemeral private keys in this domain
01397         virtual unsigned int EphemeralPrivateKeyLength() const =0;
01398         //! return length of ephemeral public keys in this domain
01399         virtual unsigned int EphemeralPublicKeyLength() const =0;
01400         //! generate ephemeral private key
01401         /*! \pre size of privateKey == PrivateEphemeralKeyLength() */
01402         virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
01403         //! generate ephemeral public key
01404         /*!     \pre size of publicKey == PublicEphemeralKeyLength() */
01405         virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
01406         //! generate private/public key pair
01407         /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */
01408         virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
01409 
01410         //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure
01411         /*! \note The ephemeral public key will always be validated.
01412                       If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
01413                 \pre size of agreedValue == AgreedValueLength()
01414                 \pre length of staticPrivateKey == StaticPrivateKeyLength()
01415                 \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
01416                 \pre length of staticOtherPublicKey == StaticPublicKeyLength()
01417                 \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
01418         */
01419         virtual bool Agree(byte *agreedValue,
01420                 const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
01421                 const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
01422                 bool validateStaticOtherPublicKey=true) const =0;
01423 
01424 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01425         bool ValidateDomainParameters(RandomNumberGenerator &rng) const
01426                 {return GetCryptoParameters().Validate(rng, 2);}
01427 #endif
01428 };
01429 
01430 // interface for password authenticated key agreement protocols, not implemented yet
01431 #if 0
01432 //! interface for protocol sessions
01433 /*! The methods should be called in the following order:
01434 
01435         InitializeSession(rng, parameters);     // or call initialize method in derived class
01436         while (true)
01437         {
01438                 if (OutgoingMessageAvailable())
01439                 {
01440                         length = GetOutgoingMessageLength();
01441                         GetOutgoingMessage(message);
01442                         ; // send outgoing message
01443                 }
01444 
01445                 if (LastMessageProcessed())
01446                         break;
01447 
01448                 ; // receive incoming message
01449                 ProcessIncomingMessage(message);
01450         }
01451         ; // call methods in derived class to obtain result of protocol session
01452 */
01453 class ProtocolSession
01454 {
01455 public:
01456         //! exception thrown when an invalid protocol message is processed
01457         class ProtocolError : public Exception
01458         {
01459         public:
01460                 ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {}
01461         };
01462 
01463         //! exception thrown when a function is called unexpectedly
01464         /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */
01465         class UnexpectedMethodCall : public Exception
01466         {
01467         public:
01468                 UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {}
01469         };
01470 
01471         ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {}
01472         virtual ~ProtocolSession() {}
01473 
01474         virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs &parameters) =0;
01475 
01476         bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;}
01477         void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;}
01478 
01479         bool HasValidState() const {return m_validState;}
01480 
01481         virtual bool OutgoingMessageAvailable() const =0;
01482         virtual unsigned int GetOutgoingMessageLength() const =0;
01483         virtual void GetOutgoingMessage(byte *message) =0;
01484 
01485         virtual bool LastMessageProcessed() const =0;
01486         virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0;
01487 
01488 protected:
01489         void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const;
01490         void CheckAndHandleInvalidState() const;
01491         void SetValidState(bool valid) {m_validState = valid;}
01492 
01493         RandomNumberGenerator *m_rng;
01494 
01495 private:
01496         bool m_throwOnProtocolError, m_validState;
01497 };
01498 
01499 class KeyAgreementSession : public ProtocolSession
01500 {
01501 public:
01502         virtual unsigned int GetAgreedValueLength() const =0;
01503         virtual void GetAgreedValue(byte *agreedValue) const =0;
01504 };
01505 
01506 class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession
01507 {
01508 public:
01509         void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, 
01510                 const byte *myId, unsigned int myIdLength, 
01511                 const byte *counterPartyId, unsigned int counterPartyIdLength, 
01512                 const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength);
01513 };
01514 
01515 class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
01516 {
01517 public:
01518         //! return whether the domain parameters stored in this object are valid
01519         virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const
01520                 {return GetCryptoParameters().Validate(rng, 2);}
01521 
01522         virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0;
01523         virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0;
01524 
01525         enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8};
01526 
01527         virtual bool IsValidRole(unsigned int role) =0;
01528         virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0;
01529 };
01530 #endif
01531 
01532 //! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation
01533 class BERDecodeErr : public InvalidArgument
01534 {
01535 public: 
01536         BERDecodeErr() : InvalidArgument("BER decode error") {}
01537         BERDecodeErr(const std::string &s) : InvalidArgument(s) {}
01538 };
01539 
01540 //! interface for encoding and decoding ASN1 objects
01541 class ASN1Object
01542 {
01543 public:
01544         virtual ~ASN1Object() {}
01545         //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules)
01546         virtual void BERDecode(BufferedTransformation &bt) =0;
01547         //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules)
01548         virtual void DEREncode(BufferedTransformation &bt) const =0;
01549         //! encode this object into a BufferedTransformation, using BER
01550         /*! this may be useful if DEREncode() would be too inefficient */
01551         virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);}
01552 };
01553 
01554 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
01555 typedef PK_SignatureScheme PK_SignatureSystem
01556 typedef PK_SignatureSchemeWithRecovery PK_SignatureSystemWithRecovery
01557 typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain
01558 typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain
01559 typedef WithPrecomputation PK_WithPrecomputation
01560 #endif
01561 
01562 NAMESPACE_END
01563 
01564 #endif

Generated on Sun Mar 14 20:44:25 2004 for Crypto++ by doxygen 1.3.6-20040222