Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

filters.h

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);        // insert filter after this one
00025 
00026 private:
00027         void operator=(const Filter &); // assignment not allowed
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         // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize)
00073         // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received))
00074         virtual void FirstPut(const byte *inString) =0;
00075         // NextPut() is called if totalLength >= firstSize+blockSize+lastSize
00076         // length parameter is always blockSize unless blockSize == 1
00077         virtual void NextPut(const byte *inString, unsigned int length) =0;
00078         // LastPut() is always called
00079         // if totalLength < firstSize then length == totalLength
00080         // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
00081         // else lastSize <= length < lastSize+blockSize
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         // this function must be called before MessageEnd()
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 = &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 // Used By ProxyFilter
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         // VC60 workaround: no T::char_type
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

Generated at Mon Jan 15 01:16:32 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000