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=DEFAULT_CHANNEL, bool blocking=true);
00026 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_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=DEFAULT_CHANNEL);
00042 size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00043 bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00044 bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
00045 bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_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 protected:
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 struct BlockPaddingSchemeDef
00255 {
00256 enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING};
00257 };
00258
00259
00260 class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper
00261 {
00262 public:
00263
00264
00265
00266 StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher = false);
00267
00268 std::string AlgorithmName() const {return m_cipher.AlgorithmName();}
00269
00270 protected:
00271 void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00272 void FirstPut(const byte *inString);
00273 void NextPutMultiple(const byte *inString, size_t length);
00274 void NextPutModifiable(byte *inString, size_t length);
00275 void LastPut(const byte *inString, size_t length);
00276
00277 static size_t LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding);
00278
00279 StreamTransformation &m_cipher;
00280 BlockPaddingScheme m_padding;
00281 unsigned int m_optimalBufferSize;
00282 };
00283
00284 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
00285 typedef StreamTransformationFilter StreamCipherFilter;
00286 #endif
00287
00288
00289 class CRYPTOPP_DLL HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper
00290 {
00291 public:
00292 HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false, int truncatedDigestSize=-1, const std::string &messagePutChannel=DEFAULT_CHANNEL, const std::string &hashPutChannel=DEFAULT_CHANNEL);
00293
00294 std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
00295 void IsolatedInitialize(const NameValuePairs ¶meters);
00296 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00297 byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);}
00298
00299 private:
00300 HashTransformation &m_hashModule;
00301 bool m_putMessage;
00302 unsigned int m_digestSize;
00303 byte *m_space;
00304 std::string m_messagePutChannel, m_hashPutChannel;
00305 };
00306
00307
00308 class CRYPTOPP_DLL HashVerificationFilter : public FilterWithBufferedInput
00309 {
00310 public:
00311 class HashVerificationFailed : public Exception
00312 {
00313 public:
00314 HashVerificationFailed()
00315 : Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerificationFilter: message hash or MAC not valid") {}
00316 };
00317
00318 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};
00319 HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1);
00320
00321 std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
00322 bool GetLastResult() const {return m_verified;}
00323
00324 protected:
00325 void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00326 void FirstPut(const byte *inString);
00327 void NextPutMultiple(const byte *inString, size_t length);
00328 void LastPut(const byte *inString, size_t length);
00329
00330 private:
00331 friend class AuthenticatedDecryptionFilter;
00332
00333 HashTransformation &m_hashModule;
00334 word32 m_flags;
00335 unsigned int m_digestSize;
00336 bool m_verified;
00337 SecByteBlock m_expectedHash;
00338 };
00339
00340 typedef HashVerificationFilter HashVerifier;
00341
00342
00343
00344 class CRYPTOPP_DLL AuthenticatedEncryptionFilter : public StreamTransformationFilter
00345 {
00346 public:
00347
00348 AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULL, bool putAAD=false, int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL, BlockPaddingScheme padding = DEFAULT_PADDING);
00349
00350 void IsolatedInitialize(const NameValuePairs ¶meters);
00351 byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
00352 size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
00353 void LastPut(const byte *inString, size_t length);
00354
00355 protected:
00356 HashFilter m_hf;
00357 };
00358
00359
00360
00361 class CRYPTOPP_DLL AuthenticatedDecryptionFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef
00362 {
00363 public:
00364 enum Flags {MAC_AT_END=0, MAC_AT_BEGIN=1, THROW_EXCEPTION=16, DEFAULT_FLAGS = THROW_EXCEPTION};
00365
00366
00367 AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1, BlockPaddingScheme padding = DEFAULT_PADDING);
00368
00369 std::string AlgorithmName() const {return m_hashVerifier.AlgorithmName();}
00370 byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
00371 size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
00372 bool GetLastResult() const {return m_hashVerifier.GetLastResult();}
00373
00374 protected:
00375 void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00376 void FirstPut(const byte *inString);
00377 void NextPutMultiple(const byte *inString, size_t length);
00378 void LastPut(const byte *inString, size_t length);
00379
00380 HashVerificationFilter m_hashVerifier;
00381 StreamTransformationFilter m_streamFilter;
00382 };
00383
00384
00385 class CRYPTOPP_DLL SignerFilter : public Unflushable<Filter>
00386 {
00387 public:
00388 SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULL, bool putMessage=false)
00389 : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator(rng)), m_putMessage(putMessage) {Detach(attachment);}
00390
00391 std::string AlgorithmName() const {return m_signer.AlgorithmName();}
00392
00393 void IsolatedInitialize(const NameValuePairs ¶meters);
00394 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00395
00396 private:
00397 RandomNumberGenerator &m_rng;
00398 const PK_Signer &m_signer;
00399 member_ptr<PK_MessageAccumulator> m_messageAccumulator;
00400 bool m_putMessage;
00401 SecByteBlock m_buf;
00402 };
00403
00404
00405 class CRYPTOPP_DLL SignatureVerificationFilter : public FilterWithBufferedInput
00406 {
00407 public:
00408 class SignatureVerificationFailed : public Exception
00409 {
00410 public:
00411 SignatureVerificationFailed()
00412 : Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {}
00413 };
00414
00415 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};
00416 SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS);
00417
00418 std::string AlgorithmName() const {return m_verifier.AlgorithmName();}
00419
00420 bool GetLastResult() const {return m_verified;}
00421
00422 protected:
00423 void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
00424 void FirstPut(const byte *inString);
00425 void NextPutMultiple(const byte *inString, size_t length);
00426 void LastPut(const byte *inString, size_t length);
00427
00428 private:
00429 const PK_Verifier &m_verifier;
00430 member_ptr<PK_MessageAccumulator> m_messageAccumulator;
00431 word32 m_flags;
00432 SecByteBlock m_signature;
00433 bool m_verified;
00434 };
00435
00436 typedef SignatureVerificationFilter VerifierFilter;
00437
00438
00439 class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink>
00440 {
00441 public:
00442 enum Behavior
00443 {
00444 DATA_ONLY = 0x00,
00445 PASS_SIGNALS = 0x01,
00446 PASS_WAIT_OBJECTS = 0x02,
00447 PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS
00448 };
00449
00450 Redirector() : m_target(NULL), m_behavior(PASS_EVERYTHING) {}
00451 Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING)
00452 : m_target(&target), m_behavior(behavior) {}
00453
00454 void Redirect(BufferedTransformation &target) {m_target = ⌖}
00455 void StopRedirection() {m_target = NULL;}
00456
00457 Behavior GetBehavior() {return (Behavior) m_behavior;}
00458 void SetBehavior(Behavior behavior) {m_behavior=behavior;}
00459 bool GetPassSignals() const {return (m_behavior & PASS_SIGNALS) != 0;}
00460 void SetPassSignals(bool pass) { if (pass) m_behavior |= PASS_SIGNALS; else m_behavior &= ~(word32) PASS_SIGNALS; }
00461 bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;}
00462 void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~(word32) PASS_WAIT_OBJECTS; }
00463
00464 bool CanModifyInput() const
00465 {return m_target ? m_target->CanModifyInput() : false;}
00466
00467 void Initialize(const NameValuePairs ¶meters, int propagation);
00468 byte * CreatePutSpace(size_t &size)
00469 {return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);}
00470 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00471 {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
00472 bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
00473 {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;}
00474 bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
00475 {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
00476
00477 byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
00478 {return m_target ? m_target->ChannelCreatePutSpace(channel, size) : (byte *)(size=0, NULL);}
00479 size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
00480 {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
00481 size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
00482 {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
00483 bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
00484 {return m_target && GetPassSignals() ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
00485 bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00486 {return m_target && GetPassSignals() ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
00487
00488 unsigned int GetMaxWaitObjectCount() const
00489 { return m_target && GetPassWaitObjects() ? m_target->GetMaxWaitObjectCount() : 0; }
00490 void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
00491 { if (m_target && GetPassWaitObjects()) m_target->GetWaitObjects(container, callStack); }
00492
00493 private:
00494 BufferedTransformation *m_target;
00495 word32 m_behavior;
00496 };
00497
00498
00499 class CRYPTOPP_DLL OutputProxy : public CustomSignalPropagation<Sink>
00500 {
00501 public:
00502 OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
00503
00504 bool GetPassSignal() const {return m_passSignal;}
00505 void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
00506
00507 byte * CreatePutSpace(size_t &size)
00508 {return m_owner.AttachedTransformation()->CreatePutSpace(size);}
00509 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00510 {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
00511 size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
00512 {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
00513 void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1)
00514 {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);}
00515 bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
00516 {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;}
00517 bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
00518 {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;}
00519
00520 byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
00521 {return m_owner.AttachedTransformation()->ChannelCreatePutSpace(channel, size);}
00522 size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
00523 {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
00524 size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
00525 {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
00526 bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
00527 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
00528 bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
00529 {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
00530
00531 private:
00532 BufferedTransformation &m_owner;
00533 bool m_passSignal;
00534 };
00535
00536
00537 class CRYPTOPP_DLL ProxyFilter : public FilterWithBufferedInput
00538 {
00539 public:
00540 ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment);
00541
00542 bool IsolatedFlush(bool hardFlush, bool blocking);
00543
00544 void SetFilter(Filter *filter);
00545 void NextPutMultiple(const byte *s, size_t len);
00546 void NextPutModifiable(byte *inString, size_t length);
00547
00548 protected:
00549 member_ptr<BufferedTransformation> m_filter;
00550 };
00551
00552
00553 class CRYPTOPP_DLL SimpleProxyFilter : public ProxyFilter
00554 {
00555 public:
00556 SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
00557 : ProxyFilter(filter, 0, 0, attachment) {}
00558
00559 void FirstPut(const byte *) {}
00560 void LastPut(const byte *, size_t) {m_filter->MessageEnd();}
00561 };
00562
00563
00564
00565 class CRYPTOPP_DLL PK_EncryptorFilter : public SimpleProxyFilter
00566 {
00567 public:
00568 PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULL)
00569 : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {}
00570 };
00571
00572
00573
00574 class CRYPTOPP_DLL PK_DecryptorFilter : public SimpleProxyFilter
00575 {
00576 public:
00577 PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL)
00578 : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {}
00579 };
00580
00581
00582 template <class T>
00583 class StringSinkTemplate : public Bufferless<Sink>
00584 {
00585 public:
00586
00587 typedef typename T::traits_type::char_type char_type;
00588
00589 StringSinkTemplate(T &output)
00590 : m_output(&output) {assert(sizeof(output[0])==1);}
00591
00592 void IsolatedInitialize(const NameValuePairs ¶meters)
00593 {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
00594
00595 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00596 {
00597 if (length > 0)
00598 {
00599 typename T::size_type size = m_output->size();
00600 if (length < size && size + length > m_output->capacity())
00601 m_output->reserve(2*size);
00602 m_output->append((const char_type *)begin, (const char_type *)begin+length);
00603 }
00604 return 0;
00605 }
00606
00607 private:
00608 T *m_output;
00609 };
00610
00611
00612 CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>;
00613 typedef StringSinkTemplate<std::string> StringSink;
00614
00615
00616 class RandomNumberSink : public Bufferless<Sink>
00617 {
00618 public:
00619 RandomNumberSink()
00620 : m_rng(NULL) {}
00621
00622 RandomNumberSink(RandomNumberGenerator &rng)
00623 : m_rng(&rng) {}
00624
00625 void IsolatedInitialize(const NameValuePairs ¶meters);
00626 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00627
00628 private:
00629 RandomNumberGenerator *m_rng;
00630 };
00631
00632
00633 class CRYPTOPP_DLL ArraySink : public Bufferless<Sink>
00634 {
00635 public:
00636 ArraySink(const NameValuePairs ¶meters = g_nullNameValuePairs) {IsolatedInitialize(parameters);}
00637 ArraySink(byte *buf, size_t size) : m_buf(buf), m_size(size), m_total(0) {}
00638
00639 size_t AvailableSize() {return SaturatingSubtract(m_size, m_total);}
00640 lword TotalPutLength() {return m_total;}
00641
00642 void IsolatedInitialize(const NameValuePairs ¶meters);
00643 byte * CreatePutSpace(size_t &size);
00644 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00645
00646 protected:
00647 byte *m_buf;
00648 size_t m_size;
00649 lword m_total;
00650 };
00651
00652
00653 class CRYPTOPP_DLL ArrayXorSink : public ArraySink
00654 {
00655 public:
00656 ArrayXorSink(byte *buf, size_t size)
00657 : ArraySink(buf, size) {}
00658
00659 size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
00660 byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);}
00661 };
00662
00663
00664 class StringStore : public Store
00665 {
00666 public:
00667 StringStore(const char *string = NULL)
00668 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00669 StringStore(const byte *string, size_t length)
00670 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00671 template <class T> StringStore(const T &string)
00672 {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00673
00674 CRYPTOPP_DLL size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00675 CRYPTOPP_DLL size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
00676
00677 private:
00678 CRYPTOPP_DLL void StoreInitialize(const NameValuePairs ¶meters);
00679
00680 const byte *m_store;
00681 size_t m_length, m_count;
00682 };
00683
00684
00685 class CRYPTOPP_DLL RandomNumberStore : public Store
00686 {
00687 public:
00688 RandomNumberStore()
00689 : m_rng(NULL), m_length(0), m_count(0) {}
00690
00691 RandomNumberStore(RandomNumberGenerator &rng, lword length)
00692 : m_rng(&rng), m_length(length), m_count(0) {}
00693
00694 bool AnyRetrievable() const {return MaxRetrievable() != 0;}
00695 lword MaxRetrievable() const {return m_length-m_count;}
00696
00697 size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00698 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
00699 {
00700 throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store");
00701 }
00702
00703 private:
00704 void StoreInitialize(const NameValuePairs ¶meters);
00705
00706 RandomNumberGenerator *m_rng;
00707 lword m_length, m_count;
00708 };
00709
00710
00711 class CRYPTOPP_DLL NullStore : public Store
00712 {
00713 public:
00714 NullStore(lword size = ULONG_MAX) : m_size(size) {}
00715 void StoreInitialize(const NameValuePairs ¶meters) {}
00716 lword MaxRetrievable() const {return m_size;}
00717 size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
00718 size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
00719
00720 private:
00721 lword m_size;
00722 };
00723
00724
00725 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter>
00726 {
00727 public:
00728 Source(BufferedTransformation *attachment = NULL)
00729 {Source::Detach(attachment);}
00730
00731 lword Pump(lword pumpMax=size_t(0)-1)
00732 {Pump2(pumpMax); return pumpMax;}
00733 unsigned int PumpMessages(unsigned int count=UINT_MAX)
00734 {PumpMessages2(count); return count;}
00735 void PumpAll()
00736 {PumpAll2();}
00737 virtual size_t Pump2(lword &byteCount, bool blocking=true) =0;
00738 virtual size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
00739 virtual size_t PumpAll2(bool blocking=true);
00740 virtual bool SourceExhausted() const =0;
00741
00742 protected:
00743 void SourceInitialize(bool pumpAll, const NameValuePairs ¶meters)
00744 {
00745 IsolatedInitialize(parameters);
00746 if (pumpAll)
00747 PumpAll();
00748 }
00749 };
00750
00751
00752 template <class T>
00753 class SourceTemplate : public Source
00754 {
00755 public:
00756 SourceTemplate<T>(BufferedTransformation *attachment)
00757 : Source(attachment) {}
00758 void IsolatedInitialize(const NameValuePairs ¶meters)
00759 {m_store.IsolatedInitialize(parameters);}
00760 size_t Pump2(lword &byteCount, bool blocking=true)
00761 {return m_store.TransferTo2(*AttachedTransformation(), byteCount, DEFAULT_CHANNEL, blocking);}
00762 size_t PumpMessages2(unsigned int &messageCount, bool blocking=true)
00763 {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, DEFAULT_CHANNEL, blocking);}
00764 size_t PumpAll2(bool blocking=true)
00765 {return m_store.TransferAllTo2(*AttachedTransformation(), DEFAULT_CHANNEL, blocking);}
00766 bool SourceExhausted() const
00767 {return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
00768 void SetAutoSignalPropagation(int propagation)
00769 {m_store.SetAutoSignalPropagation(propagation);}
00770 int GetAutoSignalPropagation() const
00771 {return m_store.GetAutoSignalPropagation();}
00772
00773 protected:
00774 T m_store;
00775 };
00776
00777
00778 class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
00779 {
00780 public:
00781 StringSource(BufferedTransformation *attachment = NULL)
00782 : SourceTemplate<StringStore>(attachment) {}
00783
00784 StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL)
00785 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00786
00787 StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULL)
00788 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
00789
00790 StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL)
00791 : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
00792 };
00793
00794
00795 typedef StringSource ArraySource;
00796
00797
00798 class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate<RandomNumberStore>
00799 {
00800 public:
00801 RandomNumberSource(RandomNumberGenerator &rng, int length, bool pumpAll, BufferedTransformation *attachment = NULL)
00802 : SourceTemplate<RandomNumberStore>(attachment)
00803 {SourceInitialize(pumpAll, MakeParameters("RandomNumberGeneratorPointer", &rng)("RandomNumberStoreSize", length));}
00804 };
00805
00806 NAMESPACE_END
00807
00808 #endif