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

filters.h

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

Generated on Wed Jul 21 19:15:25 2004 for Crypto++ by doxygen 1.3.7-20040704