00001 #ifndef CRYPTOPP_FILTERS_H
00002 #define CRYPTOPP_FILTERS_H
00003
00004 #include "cryptlib.h"
00005 #include "misc.h"
00006 #include "smartptr.h"
00007 #include "queue.h"
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00012 class Filter : virtual public BufferedTransformation
00013 {
00014 public:
00015 Filter(BufferedTransformation *outQ);
00016
00017 bool Attachable() {return true;}
00018 BufferedTransformation *AttachedTransformation() {return m_outQueue.get();}
00019 const BufferedTransformation *AttachedTransformation() const {return m_outQueue.get();}
00020 void Detach(BufferedTransformation *newOut = NULL);
00021
00022 protected:
00023 virtual void NotifyAttachmentChange() {}
00024 void Insert(Filter *nextFilter);
00025
00026 private:
00027 void operator=(const Filter &);
00028
00029 member_ptr<BufferedTransformation> m_outQueue;
00030 };
00031
00033 class TransparentFilter : public Filter
00034 {
00035 public:
00036 TransparentFilter(BufferedTransformation *outQ=NULL) : Filter(outQ) {}
00037 void Put(byte inByte) {AttachedTransformation()->Put(inByte);}
00038 void Put(const byte *inString, unsigned int length) {AttachedTransformation()->Put(inString, length);}
00039 };
00040
00042 class OpaqueFilter : public Filter
00043 {
00044 public:
00045 OpaqueFilter(BufferedTransformation *outQ=NULL) : Filter(outQ) {}
00046 void Put(byte inByte) {}
00047 void Put(const byte *inString, unsigned int length) {}
00048 };
00049
00055 class FilterWithBufferedInput : public Filter
00056 {
00057 public:
00059 FilterWithBufferedInput(unsigned int firstSize, unsigned int blockSize, unsigned int lastSize, BufferedTransformation *outQ);
00060 void Put(byte inByte);
00061 void Put(const byte *inString, unsigned int length);
00062 void MessageEnd(int propagation=-1);
00063
00067 void ForceNextPut();
00068
00069 protected:
00070 bool DidFirstPut() {return m_firstInputDone;}
00071
00072
00073
00074 virtual void FirstPut(const byte *inString) =0;
00075
00076
00077 virtual void NextPut(const byte *inString, unsigned int length) =0;
00078
00079
00080
00081
00082 virtual void LastPut(const byte *inString, unsigned int length) =0;
00083
00084 private:
00085 class BlockQueue
00086 {
00087 public:
00088 BlockQueue(unsigned int blockSize, unsigned int maxBlocks);
00089 void ResetQueue(unsigned int blockSize, unsigned int maxBlocks);
00090 const byte *GetBlock();
00091 const byte *GetContigousBlocks(unsigned int &numberOfBlocks);
00092 unsigned int GetAll(byte *outString);
00093 void Put(const byte *inString, unsigned int length);
00094 unsigned int CurrentSize() const {return m_size;}
00095 unsigned int MaxSize() const {return m_buffer.size;}
00096
00097 private:
00098 SecByteBlock m_buffer;
00099 unsigned int m_blockSize, m_maxBlocks, m_size;
00100 byte *m_begin;
00101 };
00102
00103 unsigned int m_firstSize, m_blockSize, m_lastSize;
00104 bool m_firstInputDone;
00105 BlockQueue m_queue;
00106 };
00107
00109 class FilterWithInputQueue : public Filter
00110 {
00111 public:
00112 FilterWithInputQueue(BufferedTransformation *attachment) : Filter(attachment) {}
00113 void Put(byte inByte) {m_inQueue.Put(inByte);}
00114 void Put(const byte *inString, unsigned int length) {m_inQueue.Put(inString, length);}
00115
00116 protected:
00117 ByteQueue m_inQueue;
00118 };
00119
00121 class StreamCipherFilter : public Filter
00122 {
00123 public:
00124 StreamCipherFilter(StreamCipher &c,
00125 BufferedTransformation *outQueue = NULL)
00126 : cipher(c), Filter(outQueue) {}
00127
00128 void Put(byte inByte)
00129 {AttachedTransformation()->Put(cipher.ProcessByte(inByte));}
00130
00131 void Put(const byte *inString, unsigned int length);
00132
00133 private:
00134 StreamCipher &cipher;
00135 };
00136
00138 class HashFilter : public Filter
00139 {
00140 public:
00141 HashFilter(HashModule &hm, BufferedTransformation *outQueue = NULL, bool putMessage=false)
00142 : Filter(outQueue), m_hashModule(hm), m_putMessage(putMessage) {}
00143
00144 void MessageEnd(int propagation=-1);
00145
00146 void Put(byte inByte);
00147 void Put(const byte *inString, unsigned int length);
00148
00149 private:
00150 HashModule &m_hashModule;
00151 bool m_putMessage;
00152 };
00153
00155 class HashVerifier : public FilterWithBufferedInput
00156 {
00157 public:
00158 class HashVerificationFailed : public BufferedTransformation::Err
00159 {
00160 public:
00161 HashVerificationFailed()
00162 : BufferedTransformation::Err(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not correct") {}
00163 };
00164
00165 enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16};
00166 HashVerifier(HashModule &hm, BufferedTransformation *outQueue = NULL, word32 flags = HASH_AT_BEGIN | PUT_RESULT);
00167
00168 bool GetLastResult() const {return m_verified;}
00169
00170 protected:
00171 void FirstPut(const byte *inString);
00172 void NextPut(const byte *inString, unsigned int length);
00173 void LastPut(const byte *inString, unsigned int length);
00174
00175 private:
00176 HashModule &m_hashModule;
00177 word32 m_flags;
00178 SecByteBlock m_expectedHash;
00179 bool m_verified;
00180 };
00181
00183 class SignerFilter : public Filter
00184 {
00185 public:
00186 SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *outQueue = NULL)
00187 : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewMessageAccumulator()), Filter(outQueue) {}
00188
00189 void MessageEnd(int propagation);
00190
00191 void Put(byte inByte)
00192 {m_messageAccumulator->Update(&inByte, 1);}
00193
00194 void Put(const byte *inString, unsigned int length)
00195 {m_messageAccumulator->Update(inString, length);}
00196
00197 private:
00198 RandomNumberGenerator &m_rng;
00199 const PK_Signer &m_signer;
00200 member_ptr<HashModule> m_messageAccumulator;
00201 };
00202
00204 class VerifierFilter : public Filter
00205 {
00206 public:
00207 VerifierFilter(const PK_Verifier &verifier, BufferedTransformation *outQueue = NULL)
00208 : m_verifier(verifier), m_messageAccumulator(verifier.NewMessageAccumulator())
00209 , m_signature(verifier.SignatureLength()), Filter(outQueue) {}
00210
00211
00212 void PutSignature(const byte *sig);
00213
00214 void MessageEnd(int propagation);
00215
00216 void Put(byte inByte)
00217 {m_messageAccumulator->Update(&inByte, 1);}
00218
00219 void Put(const byte *inString, unsigned int length)
00220 {m_messageAccumulator->Update(inString, length);}
00221
00222 private:
00223 const PK_Verifier &m_verifier;
00224 member_ptr<HashModule> m_messageAccumulator;
00225 SecByteBlock m_signature;
00226 };
00227
00229 class Sink : public BufferedTransformation
00230 {
00231 };
00232
00234 class BitBucket : public Sink
00235 {
00236 public:
00237 void Put(byte) {}
00238 void Put(const byte *, unsigned int) {}
00239 };
00240
00241 extern BitBucket g_bitBucket;
00242
00244 class Redirector : public Sink
00245 {
00246 public:
00247 Redirector() : m_target(NULL), m_passSignal(true) {}
00248 Redirector(BufferedTransformation &target, bool passSignal=true) : m_target(&target), m_passSignal(passSignal) {}
00249
00250 void Redirect(BufferedTransformation &target) {m_target = ⌖}
00251 void StopRedirect() {m_target = NULL;}
00252 bool GetPassSignal() const {return m_passSignal;}
00253 void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
00254
00255 void Put(byte b)
00256 {if (m_target) m_target->Put(b);}
00257 void Put(const byte *string, unsigned int len)
00258 {if (m_target) m_target->Put(string, len);}
00259 void Flush(bool completeFlush, int propagation=-1)
00260 {if (m_target && m_passSignal) m_target->Flush(completeFlush, propagation);}
00261 void MessageEnd(int propagation=-1)
00262 {if (m_target && m_passSignal) m_target->MessageEnd(propagation);}
00263 void MessageSeriesEnd(int propagation=-1)
00264 {if (m_target && m_passSignal) m_target->MessageSeriesEnd(propagation);}
00265
00266 void ChannelPut(const std::string &channel, byte b)
00267 {if (m_target) m_target->ChannelPut(channel, b);}
00268 void ChannelPut(const std::string &channel, const byte *string, unsigned int len)
00269 {if (m_target) m_target->ChannelPut(channel, string, len);}
00270 void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1)
00271 {if (m_target && m_passSignal) m_target->ChannelFlush(channel, completeFlush, propagation);}
00272 void ChannelMessageEnd(const std::string &channel, int propagation=-1)
00273 {if (m_target && m_passSignal) m_target->ChannelMessageEnd(channel, propagation);}
00274 void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1)
00275 {if (m_target && m_passSignal) m_target->ChannelMessageSeriesEnd(channel, propagation);}
00276
00277 private:
00278 BufferedTransformation *m_target;
00279 bool m_passSignal;
00280 };
00281
00282
00283 class OutputProxy : public Sink
00284 {
00285 public:
00286 OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
00287
00288 bool GetPassSignal() const {return m_passSignal;}
00289 void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
00290
00291 void Put(byte b)
00292 {m_owner.AttachedTransformation()->Put(b);}
00293 void Put(const byte *string, unsigned int len)
00294 {m_owner.AttachedTransformation()->Put(string, len);}
00295 void Flush(bool completeFlush, int propagation=-1)
00296 {if (m_passSignal) m_owner.AttachedTransformation()->Flush(completeFlush, propagation);}
00297 void MessageEnd(int propagation=-1)
00298 {if (m_passSignal) m_owner.AttachedTransformation()->MessageEnd(propagation);}
00299 void MessageSeriesEnd(int propagation=-1)
00300 {if (m_passSignal) m_owner.AttachedTransformation()->MessageSeriesEnd(propagation);}
00301
00302 void ChannelPut(const std::string &channel, byte b)
00303 {m_owner.AttachedTransformation()->ChannelPut(channel, b);}
00304 void ChannelPut(const std::string &channel, const byte *string, unsigned int len)
00305 {m_owner.AttachedTransformation()->ChannelPut(channel, string, len);}
00306 void ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1)
00307 {if (m_passSignal) m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation);}
00308 void ChannelMessageEnd(const std::string &channel, int propagation=-1)
00309 {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageEnd(channel, propagation);}
00310 void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1)
00311 {if (m_passSignal) m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation);}
00312
00313 private:
00314 BufferedTransformation &m_owner;
00315 bool m_passSignal;
00316 };
00317
00319 class ProxyFilter : public FilterWithBufferedInput
00320 {
00321 public:
00322 ProxyFilter(Filter *filter, unsigned int firstSize, unsigned int lastSize, BufferedTransformation *outQ);
00323
00324 void Flush(bool completeFlush, int propagation=-1);
00325
00326 void SetFilter(Filter *filter);
00327 void NextPut(const byte *s, unsigned int len);
00328
00329 protected:
00330 member_ptr<Filter> m_filter;
00331 OutputProxy *m_proxy;
00332 };
00333
00335 template <class T>
00336 class StringSinkTemplate : public Sink
00337 {
00338 public:
00339
00340 typedef typename T::traits_type::char_type char_type;
00341
00342 StringSinkTemplate(T &output)
00343 : m_output(output) {assert(sizeof(output[0])==1);}
00344 void Put(byte b)
00345 {m_output += (char_type)b;}
00346 void Put(const byte *str, unsigned int bc)
00347 {m_output.append((const char_type *)str, bc);}
00348
00349 private:
00350 T &m_output;
00351 };
00352
00354 typedef StringSinkTemplate<std::string> StringSink;
00355
00357 class ArraySink : public Sink
00358 {
00359 public:
00360 ArraySink(byte *buf, unsigned int size) : m_buf(buf), m_size(size), m_total(0) {}
00361
00362 unsigned int AvailableSize() {return m_size - STDMIN(m_total, (unsigned long)m_size);}
00363 unsigned long TotalPutLength() {return m_total;}
00364
00365 void Put(byte b)
00366 {
00367 if (m_total < m_size)
00368 m_buf[m_total] = b;
00369 m_total++;
00370 }
00371
00372 void Put(const byte *str, unsigned int len)
00373 {
00374 if (m_total < m_size)
00375 memcpy(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total)));
00376 m_total += len;
00377 }
00378
00379 protected:
00380 byte *m_buf;
00381 unsigned int m_size;
00382 unsigned long m_total;
00383 };
00384
00386 class ArrayXorSink : public ArraySink
00387 {
00388 public:
00389 ArrayXorSink(byte *buf, unsigned int size)
00390 : ArraySink(buf, size) {}
00391
00392 void Put(byte b)
00393 {
00394 if (m_total < m_size)
00395 m_buf[m_total] ^= b;
00396 m_total++;
00397 }
00398
00399 void Put(const byte *str, unsigned int len)
00400 {
00401 if (m_total < m_size)
00402 xorbuf(m_buf+m_total, str, STDMIN(len, (unsigned int)(m_size-m_total)));
00403 m_total += len;
00404 }
00405 };
00406
00408 class BufferedTransformationWithAutoSignal : virtual public BufferedTransformation
00409 {
00410 public:
00411 BufferedTransformationWithAutoSignal(int propagation=-1) : m_autoSignalPropagation(propagation) {}
00412
00413 void SetAutoSignalPropagation(int propagation)
00414 {m_autoSignalPropagation = propagation;}
00415 int GetAutoSignalPropagation() const
00416 {return m_autoSignalPropagation;}
00417
00418 private:
00419 int m_autoSignalPropagation;
00420 };
00421
00423 class Store : public BufferedTransformationWithAutoSignal
00424 {
00425 public:
00426 Store() : m_messageEnd(false) {}
00427
00428 void Put(byte)
00429 {}
00430 void Put(const byte *, unsigned int length)
00431 {}
00432
00433 virtual unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX) =0;
00434 virtual unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const =0;
00435
00436 unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;}
00437 bool GetNextMessage();
00438 unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX) const;
00439
00440 private:
00441 bool m_messageEnd;
00442 };
00443
00445 class StringStore : public Store
00446 {
00447 public:
00448 StringStore(const char *string)
00449 : m_store((const byte *)string), m_length(strlen(string)), m_count(0) {}
00450 StringStore(const byte *string, unsigned int length)
00451 : m_store(string), m_length(length), m_count(0) {}
00452 template <class T> StringStore(const T &string)
00453 : m_store((const byte *)string.data()), m_length(string.length()), m_count(0) {assert(sizeof(string[0])==1);}
00454
00455 unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX);
00456 unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const;
00457
00458 private:
00459 const byte *m_store;
00460 unsigned int m_length, m_count;
00461 };
00462
00464 class RandomNumberStore : public Store
00465 {
00466 public:
00467 RandomNumberStore(RandomNumberGenerator &rng, unsigned long length)
00468 : m_rng(rng), m_length(length), m_count(0) {}
00469
00470 unsigned long TransferTo(BufferedTransformation &target, unsigned long transferMax=ULONG_MAX);
00471 unsigned long CopyTo(BufferedTransformation &target, unsigned long copyMax=ULONG_MAX) const;
00472
00473 private:
00474 RandomNumberGenerator &m_rng;
00475 unsigned long m_length, m_count;
00476 };
00477
00479 class Source : public Filter
00480 {
00481 public:
00482 Source(BufferedTransformation *outQ)
00483 : Filter(outQ) {}
00484
00485 virtual unsigned long Pump(unsigned long pumpMax=ULONG_MAX) =0;
00486 virtual unsigned int PumpMessages(unsigned int count=UINT_MAX) {return 0;}
00487 void PumpAll();
00488
00489 void Put(byte)
00490 {Pump(1);}
00491 void Put(const byte *, unsigned int length)
00492 {Pump(length);}
00493 void MessageEnd(int propagation=-1)
00494 {PumpAll();}
00495 };
00496
00498 class GeneralSource : public Source
00499 {
00500 public:
00501 GeneralSource(BufferedTransformation &store, bool pumpAll, BufferedTransformation *outQueue = NULL)
00502 : Source(outQueue), m_store(store)
00503 {
00504 if (pumpAll) PumpAll();
00505 }
00506
00507 unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
00508 {return m_store.TransferTo(*AttachedTransformation(), pumpMax);}
00509 unsigned int PumpMessages(unsigned int count=UINT_MAX)
00510 {return m_store.TransferMessagesTo(*AttachedTransformation(), count);}
00511
00512 private:
00513 BufferedTransformation &m_store;
00514 };
00515
00517 class StringSource : public Source
00518 {
00519 public:
00520 StringSource(const char *string, bool pumpAll, BufferedTransformation *outQueue = NULL);
00521 StringSource(const byte *string, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = NULL);
00522
00523 #ifdef __MWERKS__ // CW60 workaround
00524 StringSource(const std::string &string, bool pumpAll, BufferedTransformation *outQueue = NULL)
00525 #else
00526 template <class T> StringSource(const T &string, bool pumpAll, BufferedTransformation *outQueue = NULL)
00527 #endif
00528 : Source(outQueue), m_store(string)
00529 {
00530 if (pumpAll)
00531 PumpAll();
00532 }
00533
00534 unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
00535 {return m_store.TransferTo(*AttachedTransformation(), pumpMax);}
00536 unsigned int PumpMessages(unsigned int count=UINT_MAX)
00537 {return m_store.TransferMessagesTo(*AttachedTransformation(), count);}
00538
00539 private:
00540 StringStore m_store;
00541 };
00542
00544 class RandomNumberSource : public Source
00545 {
00546 public:
00547 RandomNumberSource(RandomNumberGenerator &rng, unsigned int length, bool pumpAll, BufferedTransformation *outQueue = NULL);
00548
00549 unsigned long Pump(unsigned long pumpMax=ULONG_MAX)
00550 {return m_store.TransferTo(*AttachedTransformation(), pumpMax);}
00551 unsigned int PumpMessages(unsigned int count=UINT_MAX)
00552 {return m_store.TransferMessagesTo(*AttachedTransformation(), count);}
00553
00554 private:
00555 RandomNumberStore m_store;
00556 };
00557
00558 NAMESPACE_END
00559
00560 #endif