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

Generated on Sat Jul 10 22:55:24 2004 for Crypto++ by doxygen 1.3.6