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