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

Generated on Sun Oct 17 2010 02:13:04 for Crypto++ by  doxygen 1.7.1