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

filters.h

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

Generated on Tue Aug 16 08:38:41 2005 for Crypto++ by  doxygen 1.3.9.1