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