• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

filters.h

Go to the documentation of this file.
00001 #ifndef CRYPTOPP_FILTERS_H
00002 #define CRYPTOPP_FILTERS_H
00003 
00004 //! \file
00005 
00006 #include "simple.h"
00007 #include "secblock.h"
00008 #include "misc.h"
00009 #include "smartptr.h"
00010 #include "queue.h"
00011 #include "algparam.h"
00012 #include <deque>
00013 
00014 NAMESPACE_BEGIN(CryptoPP)
00015 
00016 /// provides an implementation of BufferedTransformation's attachment interface
00017 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable
00018 {
00019 public:
00020         Filter(BufferedTransformation *attachment = NULL);
00021 
00022         bool Attachable() {return true;}
00023         BufferedTransformation *AttachedTransformation();
00024         const BufferedTransformation *AttachedTransformation() const;
00025         void Detach(BufferedTransformation *newAttachment = NULL);
00026 
00027         size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00028         size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
00029 
00030         void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
00031         bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
00032         bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
00033 
00034 protected:
00035         virtual BufferedTransformation * NewDefaultAttachment() const;
00036         void Insert(Filter *nextFilter);        // insert filter after this one
00037 
00038         virtual bool ShouldPropagateMessageEnd() const {return true;}
00039         virtual bool ShouldPropagateMessageSeriesEnd() const {return true;}
00040 
00041         void PropagateInitialize(const NameValuePairs &parameters, int propagation);
00042 
00043         size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00044         size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00045         bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00046         bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00047         bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00048 
00049 private:
00050         member_ptr<BufferedTransformation> m_attachment;
00051         
00052 protected:
00053         size_t m_inputPosition;
00054         int m_continueAt;
00055 };
00056 
00057 struct CRYPTOPP_DLL FilterPutSpaceHelper
00058 {
00059         // desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace
00060         byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t desiredSize, size_t &bufferSize)
00061         {
00062                 assert(desiredSize >= minSize && bufferSize >= minSize);
00063                 if (m_tempSpace.size() < minSize)
00064                 {
00065                         byte *result = target.ChannelCreatePutSpace(channel, desiredSize);
00066                         if (desiredSize >= minSize)
00067                         {
00068                                 bufferSize = desiredSize;
00069                                 return result;
00070                         }
00071                         m_tempSpace.New(bufferSize);
00072                 }
00073 
00074                 bufferSize = m_tempSpace.size();
00075                 return m_tempSpace.begin();
00076         }
00077         byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize)
00078                 {return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);}
00079         byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t bufferSize)
00080                 {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
00081         SecByteBlock m_tempSpace;
00082 };
00083 
00084 //! measure how many byte and messages pass through, also serves as valve
00085 class CRYPTOPP_DLL MeterFilter : public Bufferless<Filter>
00086 {
00087 public:
00088         MeterFilter(BufferedTransformation *attachment=NULL, bool transparent=true)
00089                 : m_transparent(transparent) {Detach(attachment); ResetMeter();}
00090 
00091         void SetTransparent(bool transparent) {m_transparent = transparent;}
00092         void AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow = true);
00093         void ResetMeter();
00094         void IsolatedInitialize(const NameValuePairs &parameters) {ResetMeter();}
00095 
00096         lword GetCurrentMessageBytes() const {return m_currentMessageBytes;}
00097         lword GetTotalBytes() {return m_totalBytes;}
00098         unsigned int GetCurrentSeriesMessages() {return m_currentSeriesMessages;}
00099         unsigned int GetTotalMessages() {return m_totalMessages;}
00100         unsigned int GetTotalMessageSeries() {return m_totalMessageSeries;}
00101 
00102         byte * CreatePutSpace(size_t &size)
00103                 {return AttachedTransformation()->CreatePutSpace(size);}
00104         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00105         size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking);
00106         bool IsolatedMessageSeriesEnd(bool blocking);
00107 
00108 private:
00109         size_t PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable);
00110         bool ShouldPropagateMessageEnd() const {return m_transparent;}
00111         bool ShouldPropagateMessageSeriesEnd() const {return m_transparent;}
00112 
00113         struct MessageRange
00114         {
00115                 inline bool operator<(const MessageRange &b) const      // BCB2006 workaround: this has to be a member function
00116                         {return message < b.message || (message == b.message && position < b.position);}
00117                 unsigned int message; lword position; lword size;
00118         };
00119 
00120         bool m_transparent;
00121         lword m_currentMessageBytes, m_totalBytes;
00122         unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries;
00123         std::deque<MessageRange> m_rangesToSkip;
00124         byte *m_begin;
00125         size_t m_length;
00126 };
00127 
00128 //! _
00129 class CRYPTOPP_DLL TransparentFilter : public MeterFilter
00130 {
00131 public:
00132         TransparentFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, true) {}
00133 };
00134 
00135 //! _
00136 class CRYPTOPP_DLL OpaqueFilter : public MeterFilter
00137 {
00138 public:
00139         OpaqueFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, false) {}
00140 };
00141 
00142 /*! FilterWithBufferedInput divides up the input stream into
00143         a first block, a number of middle blocks, and a last block.
00144         First and last blocks are optional, and middle blocks may
00145         be a stream instead (i.e. blockSize == 1).
00146 */
00147 class CRYPTOPP_DLL FilterWithBufferedInput : public Filter
00148 {
00149 public:
00150         FilterWithBufferedInput(BufferedTransformation *attachment);
00151         //! firstSize and lastSize may be 0, blockSize must be at least 1
00152         FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment);
00153 
00154         void IsolatedInitialize(const NameValuePairs &parameters);
00155         size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00156         {
00157                 return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false);
00158         }
00159         size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
00160         {
00161                 return PutMaybeModifiable(inString, length, messageEnd, blocking, true);
00162         }
00163         /*! calls ForceNextPut() if hardFlush is true */
00164         bool IsolatedFlush(bool hardFlush, bool blocking);
00165 
00166         /*! The input buffer may contain more than blockSize bytes if lastSize != 0.
00167                 ForceNextPut() forces a call to NextPut() if this is the case.
00168         */
00169         void ForceNextPut();
00170 
00171 protected:
00172         bool DidFirstPut() {return m_firstInputDone;}
00173 
00174         virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
00175                 {InitializeDerived(parameters);}
00176         virtual void InitializeDerived(const NameValuePairs &parameters) {}
00177         // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize)
00178         // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received))
00179         virtual void FirstPut(const byte *inString) =0;
00180         // NextPut() is called if totalLength >= firstSize+blockSize+lastSize
00181         virtual void NextPutSingle(const byte *inString) {assert(false);}
00182         // Same as NextPut() except length can be a multiple of blockSize
00183         // Either NextPut() or NextPutMultiple() must be overriden
00184         virtual void NextPutMultiple(const byte *inString, size_t length);
00185         // Same as NextPutMultiple(), but inString can be modified
00186         virtual void NextPutModifiable(byte *inString, size_t length)
00187                 {NextPutMultiple(inString, length);}
00188         // LastPut() is always called
00189         // if totalLength < firstSize then length == totalLength
00190         // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
00191         // else lastSize <= length < lastSize+blockSize
00192         virtual void LastPut(const byte *inString, size_t length) =0;
00193         virtual void FlushDerived() {}
00194 
00195 protected:
00196         size_t PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable);
00197         void NextPutMaybeModifiable(byte *inString, size_t length, bool modifiable)
00198         {
00199                 if (modifiable) NextPutModifiable(inString, length);
00200                 else NextPutMultiple(inString, length);
00201         }
00202 
00203         // This function should no longer be used, put this here to cause a compiler error
00204         // if someone tries to override NextPut().
00205         virtual int NextPut(const byte *inString, size_t length) {assert(false); return 0;}
00206 
00207         class BlockQueue
00208         {
00209         public:
00210                 void ResetQueue(size_t blockSize, size_t maxBlocks);
00211                 byte *GetBlock();
00212                 byte *GetContigousBlocks(size_t &numberOfBytes);
00213                 size_t GetAll(byte *outString);
00214                 void Put(const byte *inString, size_t length);
00215                 size_t CurrentSize() const {return m_size;}
00216                 size_t MaxSize() const {return m_buffer.size();}
00217 
00218         private:
00219                 SecByteBlock m_buffer;
00220                 size_t m_blockSize, m_maxBlocks, m_size;
00221                 byte *m_begin;
00222         };
00223 
00224         size_t m_firstSize, m_blockSize, m_lastSize;
00225         bool m_firstInputDone;
00226         BlockQueue m_queue;
00227 };
00228 
00229 //! _
00230 class CRYPTOPP_DLL FilterWithInputQueue : public Filter
00231 {
00232 public:
00233         FilterWithInputQueue(BufferedTransformation *attachment=NULL) : Filter(attachment) {}
00234 
00235         size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00236         {
00237                 if (!blocking)
00238                         throw BlockingInputOnly("FilterWithInputQueue");
00239                 
00240                 m_inQueue.Put(inString, length);
00241                 if (messageEnd)
00242                 {
00243                         IsolatedMessageEnd(blocking);
00244                         Output(0, NULL, 0, messageEnd, blocking);
00245                 }
00246                 return 0;
00247         }
00248 
00249 protected:
00250         virtual bool IsolatedMessageEnd(bool blocking) =0;
00251         void IsolatedInitialize(const NameValuePairs &parameters) {m_inQueue.Clear();}
00252 
00253         ByteQueue m_inQueue;
00254 };
00255 
00256 struct BlockPaddingSchemeDef
00257 {
00258         enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
00259 };
00260 
00261 //! Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed
00262 class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper
00263 {
00264 public:
00265         /*! DEFAULT_PADDING means PKCS_PADDING if c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0 (e.g. ECB or CBC mode),
00266                 otherwise NO_PADDING (OFB, CFB, CTR, CBC-CTS modes).
00267                 See http://www.weidai.com/scan-mirror/csp.html for details of the padding schemes. */
00268         StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher = false);
00269 
00270         std::string AlgorithmName() const {return m_cipher.AlgorithmName();}
00271 
00272 protected:
00273         void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00274         void FirstPut(const byte *inString);
00275         void NextPutMultiple(const byte *inString, size_t length);
00276         void NextPutModifiable(byte *inString, size_t length);
00277         void LastPut(const byte *inString, size_t length);
00278 
00279         static size_t LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding);
00280 
00281         StreamTransformation &m_cipher;
00282         BlockPaddingScheme m_padding;
00283         unsigned int m_optimalBufferSize;
00284 };
00285 
00286 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00287 typedef StreamTransformationFilter StreamCipherFilter;
00288 #endif
00289 
00290 //! Filter Wrapper for HashTransformation
00291 class CRYPTOPP_DLL HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper
00292 {
00293 public:
00294         HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false, int truncatedDigestSize=-1, const std::string &messagePutChannel=DEFAULT_CHANNEL, const std::string &hashPutChannel=DEFAULT_CHANNEL);
00295 
00296         std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
00297         void IsolatedInitialize(const NameValuePairs &parameters);
00298         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00299         byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);}
00300 
00301 private:
00302         HashTransformation &m_hashModule;
00303         bool m_putMessage;
00304         unsigned int m_digestSize;
00305         byte *m_space;
00306         std::string m_messagePutChannel, m_hashPutChannel;
00307 };
00308 
00309 //! Filter Wrapper for HashTransformation
00310 class CRYPTOPP_DLL HashVerificationFilter : public FilterWithBufferedInput
00311 {
00312 public:
00313         class HashVerificationFailed : public Exception
00314         {
00315         public:
00316                 HashVerificationFailed()
00317                         : Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerificationFilter: message hash or MAC not valid") {}
00318         };
00319 
00320         enum Flags {HASH_AT_END=0, HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT};
00321         HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1);
00322 
00323         std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
00324         bool GetLastResult() const {return m_verified;}
00325 
00326 protected:
00327         void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00328         void FirstPut(const byte *inString);
00329         void NextPutMultiple(const byte *inString, size_t length);
00330         void LastPut(const byte *inString, size_t length);
00331 
00332 private:
00333         friend class AuthenticatedDecryptionFilter;
00334 
00335         HashTransformation &m_hashModule;
00336         word32 m_flags;
00337         unsigned int m_digestSize;
00338         bool m_verified;
00339         SecByteBlock m_expectedHash;
00340 };
00341 
00342 typedef HashVerificationFilter HashVerifier;    // for backwards compatibility
00343 
00344 //! Filter wrapper for encrypting with AuthenticatedSymmetricCipher, optionally handling padding/unpadding when needed
00345 /*! Additional authenticated data should be given in channel "AAD". If putAAD is true, AAD will be Put() to the attached BufferedTransformation in channel "AAD". */
00346 class CRYPTOPP_DLL AuthenticatedEncryptionFilter : public StreamTransformationFilter
00347 {
00348 public:
00349         /*! See StreamTransformationFilter for documentation on BlockPaddingScheme  */
00350         AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULL, bool putAAD=false, int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL, BlockPaddingScheme padding = DEFAULT_PADDING);
00351 
00352         void IsolatedInitialize(const NameValuePairs &parameters);
00353         byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
00354         size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
00355         void LastPut(const byte *inString, size_t length);
00356 
00357 protected:
00358         HashFilter m_hf;
00359 };
00360 
00361 //! Filter wrapper for decrypting with AuthenticatedSymmetricCipher, optionally handling padding/unpadding when needed
00362 /*! Additional authenticated data should be given in channel "AAD". */
00363 class CRYPTOPP_DLL AuthenticatedDecryptionFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef
00364 {
00365 public:
00366         enum Flags {MAC_AT_END=0, MAC_AT_BEGIN=1, THROW_EXCEPTION=16, DEFAULT_FLAGS = THROW_EXCEPTION};
00367 
00368         /*! See StreamTransformationFilter for documentation on BlockPaddingScheme  */
00369         AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1, BlockPaddingScheme padding = DEFAULT_PADDING);
00370 
00371         std::string AlgorithmName() const {return m_hashVerifier.AlgorithmName();}
00372         byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
00373         size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
00374         bool GetLastResult() const {return m_hashVerifier.GetLastResult();}
00375 
00376 protected:
00377         void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00378         void FirstPut(const byte *inString);
00379         void NextPutMultiple(const byte *inString, size_t length);
00380         void LastPut(const byte *inString, size_t length);
00381 
00382         HashVerificationFilter m_hashVerifier;
00383         StreamTransformationFilter m_streamFilter;
00384 };
00385 
00386 //! Filter Wrapper for PK_Signer
00387 class CRYPTOPP_DLL SignerFilter : public Unflushable<Filter>
00388 {
00389 public:
00390         SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULL, bool putMessage=false)
00391                 : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator(rng)), m_putMessage(putMessage) {Detach(attachment);}
00392 
00393         std::string AlgorithmName() const {return m_signer.AlgorithmName();}
00394 
00395         void IsolatedInitialize(const NameValuePairs &parameters);
00396         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00397 
00398 private:
00399         RandomNumberGenerator &m_rng;
00400         const PK_Signer &m_signer;
00401         member_ptr<PK_MessageAccumulator> m_messageAccumulator;
00402         bool m_putMessage;
00403         SecByteBlock m_buf;
00404 };
00405 
00406 //! Filter Wrapper for PK_Verifier
00407 class CRYPTOPP_DLL SignatureVerificationFilter : public FilterWithBufferedInput
00408 {
00409 public:
00410         class SignatureVerificationFailed : public Exception
00411         {
00412         public:
00413                 SignatureVerificationFailed()
00414                         : Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {}
00415         };
00416 
00417         enum Flags {SIGNATURE_AT_END=0, SIGNATURE_AT_BEGIN=1, PUT_MESSAGE=2, PUT_SIGNATURE=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT};
00418         SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
00419 
00420         std::string AlgorithmName() const {return m_verifier.AlgorithmName();}
00421 
00422         bool GetLastResult() const {return m_verified;}
00423 
00424 protected:
00425         void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00426         void FirstPut(const byte *inString);
00427         void NextPutMultiple(const byte *inString, size_t length);
00428         void LastPut(const byte *inString, size_t length);
00429 
00430 private:
00431         const PK_Verifier &m_verifier;
00432         member_ptr<PK_MessageAccumulator> m_messageAccumulator;
00433         word32 m_flags;
00434         SecByteBlock m_signature;
00435         bool m_verified;
00436 };
00437 
00438 typedef SignatureVerificationFilter VerifierFilter;     // for backwards compatibility
00439 
00440 //! Redirect input to another BufferedTransformation without owning it
00441 class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink>
00442 {
00443 public:
00444         enum Behavior
00445         {
00446                 DATA_ONLY = 0x00,
00447                 PASS_SIGNALS = 0x01,
00448                 PASS_WAIT_OBJECTS = 0x02,
00449                 PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS
00450         };
00451 
00452         Redirector() : m_target(NULL), m_behavior(PASS_EVERYTHING) {}
00453         Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING)
00454                 : m_target(&target), m_behavior(behavior) {}
00455 
00456         void Redirect(BufferedTransformation &target) {m_target = &target;}
00457         void StopRedirection() {m_target = NULL;}
00458 
00459         Behavior GetBehavior() {return (Behavior) m_behavior;}
00460         void SetBehavior(Behavior behavior) {m_behavior=behavior;}
00461         bool GetPassSignals() const {return (m_behavior & PASS_SIGNALS) != 0;}
00462         void SetPassSignals(bool pass) { if (pass) m_behavior |= PASS_SIGNALS; else m_behavior &= ~(word32) PASS_SIGNALS; }
00463         bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;}
00464         void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~(word32) PASS_WAIT_OBJECTS; }
00465 
00466         bool CanModifyInput() const
00467                 {return m_target ? m_target->CanModifyInput() : false;}
00468 
00469         void Initialize(const NameValuePairs &parameters, int propagation);
00470         byte * CreatePutSpace(size_t &size)
00471                 {return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);}
00472         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00473                 {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
00474         bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
00475                 {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;}
00476         bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
00477                 {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
00478 
00479         byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
00480                 {return m_target ? m_target->ChannelCreatePutSpace(channel, size) : (byte *)(size=0, NULL);}
00481         size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
00482                 {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
00483         size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
00484                 {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
00485         bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
00486                 {return m_target && GetPassSignals() ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
00487         bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00488                 {return m_target && GetPassSignals() ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
00489 
00490         unsigned int GetMaxWaitObjectCount() const
00491                 { return m_target && GetPassWaitObjects() ? m_target->GetMaxWaitObjectCount() : 0; }
00492         void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
00493                 { if (m_target && GetPassWaitObjects()) m_target->GetWaitObjects(container, callStack); }
00494 
00495 private:
00496         BufferedTransformation *m_target;
00497         word32 m_behavior;
00498 };
00499 
00500 // Used By ProxyFilter
00501 class CRYPTOPP_DLL OutputProxy : public CustomSignalPropagation<Sink>
00502 {
00503 public:
00504         OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
00505 
00506         bool GetPassSignal() const {return m_passSignal;}
00507         void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
00508 
00509         byte * CreatePutSpace(size_t &size)
00510                 {return m_owner.AttachedTransformation()->CreatePutSpace(size);}
00511         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00512                 {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
00513         size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
00514                 {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
00515         void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
00516                 {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);}
00517         bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
00518                 {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;}
00519         bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
00520                 {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;}
00521 
00522         byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
00523                 {return m_owner.AttachedTransformation()->ChannelCreatePutSpace(channel, size);}
00524         size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
00525                 {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
00526         size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
00527                 {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
00528         bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
00529                 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
00530         bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00531                 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
00532 
00533 private:
00534         BufferedTransformation &m_owner;
00535         bool m_passSignal;
00536 };
00537 
00538 //! Base class for Filter classes that are proxies for a chain of other filters.
00539 class CRYPTOPP_DLL ProxyFilter : public FilterWithBufferedInput
00540 {
00541 public:
00542         ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment);
00543 
00544         bool IsolatedFlush(bool hardFlush, bool blocking);
00545 
00546         void SetFilter(Filter *filter);
00547         void NextPutMultiple(const byte *s, size_t len);
00548         void NextPutModifiable(byte *inString, size_t length);
00549 
00550 protected:
00551         member_ptr<BufferedTransformation> m_filter;
00552 };
00553 
00554 //! simple proxy filter that doesn't modify the underlying filter's input or output
00555 class CRYPTOPP_DLL SimpleProxyFilter : public ProxyFilter
00556 {
00557 public:
00558         SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
00559                 : ProxyFilter(filter, 0, 0, attachment) {}
00560 
00561         void FirstPut(const byte *) {}
00562         void LastPut(const byte *, size_t) {m_filter->MessageEnd();}
00563 };
00564 
00565 //! proxy for the filter created by PK_Encryptor::CreateEncryptionFilter
00566 /*! This class is here just to provide symmetry with VerifierFilter. */
00567 class CRYPTOPP_DLL PK_EncryptorFilter : public SimpleProxyFilter
00568 {
00569 public:
00570         PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULL)
00571                 : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {}
00572 };
00573 
00574 //! proxy for the filter created by PK_Decryptor::CreateDecryptionFilter
00575 /*! This class is here just to provide symmetry with SignerFilter. */
00576 class CRYPTOPP_DLL PK_DecryptorFilter : public SimpleProxyFilter
00577 {
00578 public:
00579         PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL)
00580                 : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {}
00581 };
00582 
00583 //! Append input to a string object
00584 template <class T>
00585 class StringSinkTemplate : public Bufferless<Sink>
00586 {
00587 public:
00588         // VC60 workaround: no T::char_type
00589         typedef typename T::traits_type::char_type char_type;
00590 
00591         StringSinkTemplate(T &output)
00592                 : m_output(&output) {assert(sizeof(output[0])==1);}
00593 
00594         void IsolatedInitialize(const NameValuePairs &parameters)
00595                 {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
00596 
00597         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00598         {
00599                 if (length > 0)
00600                 {
00601                         typename T::size_type size = m_output->size();
00602                         if (length < size && size + length > m_output->capacity())
00603                                 m_output->reserve(2*size);
00604                 m_output->append((const char_type *)begin, (const char_type *)begin+length);
00605                 }
00606                 return 0;
00607         }
00608 
00609 private:        
00610         T *m_output;
00611 };
00612 
00613 //! Append input to an std::string
00614 CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>;
00615 typedef StringSinkTemplate<std::string> StringSink;
00616 
00617 //! incorporates input into RNG as additional entropy
00618 class RandomNumberSink : public Bufferless<Sink>
00619 {
00620 public:
00621         RandomNumberSink()
00622                 : m_rng(NULL) {}
00623 
00624         RandomNumberSink(RandomNumberGenerator &rng)
00625                 : m_rng(&rng) {}
00626 
00627         void IsolatedInitialize(const NameValuePairs &parameters);
00628         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00629 
00630 private:
00631         RandomNumberGenerator *m_rng;
00632 };
00633 
00634 //! Copy input to a memory buffer
00635 class CRYPTOPP_DLL ArraySink : public Bufferless<Sink>
00636 {
00637 public:
00638         ArraySink(const NameValuePairs &parameters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
00639         ArraySink(byte *buf, size_t size) : m_buf(buf), m_size(size), m_total(0) {}
00640 
00641         size_t AvailableSize() {return SaturatingSubtract(m_size, m_total);}
00642         lword TotalPutLength() {return m_total;}
00643 
00644         void IsolatedInitialize(const NameValuePairs &parameters);
00645         byte * CreatePutSpace(size_t &size);
00646         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00647 
00648 protected:
00649         byte *m_buf;
00650         size_t m_size;
00651         lword m_total;
00652 };
00653 
00654 //! Xor input to a memory buffer
00655 class CRYPTOPP_DLL ArrayXorSink : public ArraySink
00656 {
00657 public:
00658         ArrayXorSink(byte *buf, size_t size)
00659                 : ArraySink(buf, size) {}
00660 
00661         size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00662         byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);}
00663 };
00664 
00665 //! string-based implementation of Store interface
00666 class StringStore : public Store
00667 {
00668 public:
00669         StringStore(const char *string = NULL)
00670                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00671         StringStore(const byte *string, size_t length)
00672                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00673         template <class T> StringStore(const T &string)
00674                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00675 
00676         CRYPTOPP_DLL size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00677         CRYPTOPP_DLL size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
00678 
00679 private:
00680         CRYPTOPP_DLL void StoreInitialize(const NameValuePairs &parameters);
00681 
00682         const byte *m_store;
00683         size_t m_length, m_count;
00684 };
00685 
00686 //! RNG-based implementation of Source interface
00687 class CRYPTOPP_DLL RandomNumberStore : public Store
00688 {
00689 public:
00690         RandomNumberStore()
00691                 : m_rng(NULL), m_length(0), m_count(0) {}
00692 
00693         RandomNumberStore(RandomNumberGenerator &rng, lword length)
00694                 : m_rng(&rng), m_length(length), m_count(0) {}
00695 
00696         bool AnyRetrievable() const {return MaxRetrievable() != 0;}
00697         lword MaxRetrievable() const {return m_length-m_count;}
00698 
00699         size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00700         size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
00701         {
00702                 throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store");
00703         }
00704 
00705 private:
00706         void StoreInitialize(const NameValuePairs &parameters);
00707 
00708         RandomNumberGenerator *m_rng;
00709         lword m_length, m_count;
00710 };
00711 
00712 //! empty store
00713 class CRYPTOPP_DLL NullStore : public Store
00714 {
00715 public:
00716         NullStore(lword size = ULONG_MAX) : m_size(size) {}
00717         void StoreInitialize(const NameValuePairs &parameters) {}
00718         lword MaxRetrievable() const {return m_size;}
00719         size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00720         size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
00721 
00722 private:
00723         lword m_size;
00724 };
00725 
00726 //! A Filter that pumps data into its attachment as input
00727 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter>
00728 {
00729 public:
00730         Source(BufferedTransformation *attachment = NULL)
00731                 {Source::Detach(attachment);}
00732 
00733         lword Pump(lword pumpMax=size_t(0)-1)
00734                 {Pump2(pumpMax); return pumpMax;}
00735         unsigned int PumpMessages(unsigned int count=UINT_MAX)
00736                 {PumpMessages2(count); return count;}
00737         void PumpAll()
00738                 {PumpAll2();}
00739         virtual size_t Pump2(lword &byteCount, bool blocking=true) =0;
00740         virtual size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
00741         virtual size_t PumpAll2(bool blocking=true);
00742         virtual bool SourceExhausted() const =0;
00743 
00744 protected:
00745         void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
00746         {
00747                 IsolatedInitialize(parameters);
00748                 if (pumpAll)
00749                         PumpAll();
00750         }
00751 };
00752 
00753 //! Turn a Store into a Source
00754 template <class T>
00755 class SourceTemplate : public Source
00756 {
00757 public:
00758         SourceTemplate<T>(BufferedTransformation *attachment)
00759                 : Source(attachment) {}
00760         void IsolatedInitialize(const NameValuePairs &parameters)
00761                 {m_store.IsolatedInitialize(parameters);}
00762         size_t Pump2(lword &byteCount, bool blocking=true)
00763                 {return m_store.TransferTo2(*AttachedTransformation(), byteCount, DEFAULT_CHANNEL, blocking);}
00764         size_t PumpMessages2(unsigned int &messageCount, bool blocking=true)
00765                 {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, DEFAULT_CHANNEL, blocking);}
00766         size_t PumpAll2(bool blocking=true)
00767                 {return m_store.TransferAllTo2(*AttachedTransformation(), DEFAULT_CHANNEL, blocking);}
00768         bool SourceExhausted() const
00769                 {return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
00770         void SetAutoSignalPropagation(int propagation)
00771                 {m_store.SetAutoSignalPropagation(propagation);}
00772         int GetAutoSignalPropagation() const
00773                 {return m_store.GetAutoSignalPropagation();}
00774 
00775 protected:
00776         T m_store;
00777 };
00778 
00779 //! string-based implementation of Source interface
00780 class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
00781 {
00782 public:
00783         StringSource(BufferedTransformation *attachment = NULL)
00784                 : SourceTemplate<StringStore>(attachment) {}
00785         //! zero terminated string as source
00786         StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
00787                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00788         //! binary byte array as source
00789         StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULL)
00790                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00791         //! std::string as source
00792         StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
00793                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00794 };
00795 
00796 //! use the third constructor for an array source
00797 typedef StringSource ArraySource;
00798 
00799 //! RNG-based implementation of Source interface
00800 class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate<RandomNumberStore>
00801 {
00802 public:
00803         RandomNumberSource(RandomNumberGenerator &rng, int length, bool pumpAll, BufferedTransformation *attachment = NULL)
00804                 : SourceTemplate<RandomNumberStore>(attachment) 
00805                 {SourceInitialize(pumpAll, MakeParameters("RandomNumberGeneratorPointer", &rng)("RandomNumberStoreSize", length));}
00806 };
00807 
00808 NAMESPACE_END
00809 
00810 #endif

Generated on Mon Aug 9 2010 15:56:34 for Crypto++ by  doxygen 1.7.1