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