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