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

Generated on Tue Jul 8 23:34:15 2003 for Crypto++ by doxygen 1.3.2