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 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 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 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 TransparentFilter : public MeterFilter
00111 {
00112 public:
00113         TransparentFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, true) {}
00114 };
00115 
00116 //! .
00117 class 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 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 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 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 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 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 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<PK_MessageAccumulator> m_messageAccumulator;
00329         bool m_putMessage;
00330         SecByteBlock m_buf;
00331 };
00332 
00333 //! Filter Wrapper for PK_Verifier
00334 class 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<PK_MessageAccumulator> 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 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 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 ProxyFilter : public FilterWithBufferedInput
00439 {
00440 public:
00441         ProxyFilter(BufferedTransformation *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *attachment);
00442 
00443         bool IsolatedFlush(bool hardFlush, bool blocking);
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 };
00451 
00452 //! simple proxy filter that doesn't modify the underlying filter's input or output
00453 class SimpleProxyFilter : public ProxyFilter
00454 {
00455 public:
00456         SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
00457                 : ProxyFilter(filter, 0, 0, attachment) {}
00458 
00459         void FirstPut(const byte *) {}
00460         void LastPut(const byte *, unsigned int) {m_filter->MessageEnd();}
00461 };
00462 
00463 //! proxy for the filter created by PK_Encryptor::CreateEncryptionFilter
00464 /*! This class is here just to provide symmetry with VerifierFilter. */
00465 class PK_EncryptorFilter : public SimpleProxyFilter
00466 {
00467 public:
00468         PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULL)
00469                 : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {}
00470 };
00471 
00472 //! proxy for the filter created by PK_Decryptor::CreateDecryptionFilter
00473 /*! This class is here just to provide symmetry with SignerFilter. */
00474 class PK_DecryptorFilter : public SimpleProxyFilter
00475 {
00476 public:
00477         PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL)
00478                 : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {}
00479 };
00480 
00481 //! Append input to a string object
00482 template <class T>
00483 class StringSinkTemplate : public Bufferless<Sink>
00484 {
00485 public:
00486         // VC60 workaround: no T::char_type
00487         typedef typename T::traits_type::char_type char_type;
00488 
00489         StringSinkTemplate(T &output)
00490                 : m_output(&output) {assert(sizeof(output[0])==1);}
00491 
00492         void IsolatedInitialize(const NameValuePairs &parameters)
00493                 {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
00494 
00495         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking)
00496         {
00497                 if (length > 0)
00498                 {
00499                         typename T::size_type size = m_output->size();
00500                         if (length < size && size + length > m_output->capacity())
00501                                 m_output->reserve(2*size);
00502                         m_output->append((const char_type *)begin, (const char_type *)begin+length);
00503                 }
00504                 return 0;
00505         }
00506 
00507 private:        
00508         T *m_output;
00509 };
00510 
00511 //! Append input to an std::string
00512 typedef StringSinkTemplate<std::string> StringSink;
00513 
00514 //! Copy input to a memory buffer
00515 class ArraySink : public Bufferless<Sink>
00516 {
00517 public:
00518         ArraySink(const NameValuePairs &parameters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
00519         ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {}
00520 
00521         unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);}
00522         unsigned long TotalPutLength() {return m_total;}
00523 
00524         void IsolatedInitialize(const NameValuePairs &parameters);
00525         byte * CreatePutSpace(unsigned int &size);
00526         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
00527 
00528 protected:
00529         byte *m_buf;
00530         unsigned int m_size;
00531         unsigned long m_total;
00532 };
00533 
00534 //! Xor input to a memory buffer
00535 class ArrayXorSink : public ArraySink
00536 {
00537 public:
00538         ArrayXorSink(byte *buf, unsigned int size)
00539                 : ArraySink(buf, size) {}
00540 
00541         unsigned int Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking);
00542         byte * CreatePutSpace(unsigned int &size) {return BufferedTransformation::CreatePutSpace(size);}
00543 };
00544 
00545 //! .
00546 class StringStore : public Store
00547 {
00548 public:
00549         StringStore(const char *string = NULL)
00550                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00551         StringStore(const byte *string, unsigned int length)
00552                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00553         template <class T> StringStore(const T &string)
00554                 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00555 
00556         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00557         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
00558 
00559 private:
00560         void StoreInitialize(const NameValuePairs &parameters);
00561 
00562         const byte *m_store;
00563         unsigned int m_length, m_count;
00564 };
00565 
00566 //! .
00567 class RandomNumberStore : public Store
00568 {
00569 public:
00570         RandomNumberStore(RandomNumberGenerator &rng, unsigned long length)
00571                 : m_rng(rng), m_length(length), m_count(0) {}
00572 
00573         bool AnyRetrievable() const {return MaxRetrievable() != 0;}
00574         unsigned long MaxRetrievable() const {return m_length-m_count;}
00575 
00576         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00577         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const
00578         {
00579                 throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store");
00580         }
00581 
00582 private:
00583         void StoreInitialize(const NameValuePairs &parameters) {m_count = 0;}
00584 
00585         RandomNumberGenerator &m_rng;
00586         const unsigned long m_length;
00587         unsigned long m_count;
00588 };
00589 
00590 //! .
00591 class NullStore : public Store
00592 {
00593 public:
00594         NullStore(unsigned long size = ULONG_MAX) : m_size(size) {}
00595         void StoreInitialize(const NameValuePairs &parameters) {}
00596         unsigned long MaxRetrievable() const {return m_size;}
00597         unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true);
00598         unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const;
00599 
00600 private:
00601         unsigned long m_size;
00602 };
00603 
00604 //! A Filter that pumps data into its attachment as input
00605 class Source : public InputRejecting<Filter>
00606 {
00607 public:
00608         Source(BufferedTransformation *attachment)
00609                 : InputRejecting<Filter>(attachment) {}
00610 
00611         unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
00612                 {Pump2(pumpMax); return pumpMax;}
00613         unsigned int PumpMessages(unsigned int count=UINT_MAX)
00614                 {PumpMessages2(count); return count;}
00615         void PumpAll()
00616                 {PumpAll2();}
00617         virtual unsigned int Pump2(unsigned long &byteCount, bool blocking=true) =0;
00618         virtual unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
00619         virtual unsigned int PumpAll2(bool blocking=true);
00620         virtual bool SourceExhausted() const =0;
00621 
00622 protected:
00623         void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
00624         {
00625                 IsolatedInitialize(parameters);
00626                 if (pumpAll)
00627                         PumpAll();
00628         }
00629 };
00630 
00631 //! Turn a Store into a Source
00632 template <class T>
00633 class SourceTemplate : public Source
00634 {
00635 public:
00636         SourceTemplate<T>(BufferedTransformation *attachment)
00637                 : Source(attachment) {}
00638         SourceTemplate<T>(BufferedTransformation *attachment, T store)
00639                 : Source(attachment), m_store(store) {}
00640         void IsolatedInitialize(const NameValuePairs &parameters)
00641                 {m_store.IsolatedInitialize(parameters);}
00642         unsigned int Pump2(unsigned long &byteCount, bool blocking=true)
00643                 {return m_store.TransferTo2(*AttachedTransformation(), byteCount, NULL_CHANNEL, blocking);}
00644         unsigned int PumpMessages2(unsigned int &messageCount, bool blocking=true)
00645                 {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, NULL_CHANNEL, blocking);}
00646         unsigned int PumpAll2(bool blocking=true)
00647                 {return m_store.TransferAllTo2(*AttachedTransformation(), NULL_CHANNEL, blocking);}
00648         bool SourceExhausted() const
00649                 {return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
00650         void SetAutoSignalPropagation(int propagation)
00651                 {m_store.SetAutoSignalPropagation(propagation);}
00652         int GetAutoSignalPropagation() const
00653                 {return m_store.GetAutoSignalPropagation();}
00654 
00655 protected:
00656         T m_store;
00657 };
00658 
00659 //! .
00660 class StringSource : public SourceTemplate<StringStore>
00661 {
00662 public:
00663         StringSource(BufferedTransformation *attachment = NULL)
00664                 : SourceTemplate<StringStore>(attachment) {}
00665         StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
00666                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00667         StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
00668                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00669 
00670 #ifdef __MWERKS__       // CW60 workaround
00671         StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
00672 #else
00673         template <class T> StringSource(const T &string, bool pumpAll, BufferedTransformation *attachment = NULL)
00674 #endif
00675                 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00676 };
00677 
00678 //! .
00679 class RandomNumberSource : public SourceTemplate<RandomNumberStore>
00680 {
00681 public:
00682         RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *attachment = NULL)
00683                 : SourceTemplate<RandomNumberStore>(attachment, RandomNumberStore(rng, length)) {if (pumpAll) PumpAll();}
00684 };
00685 
00686 NAMESPACE_END
00687 
00688 #endif

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