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