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 Fri Aug 13 09:56:53 2004 for Crypto++ by doxygen 1.3.7