filters.h 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529
  1. // filters.h - originally written and placed in the public domain by Wei Dai
  2. /// \file filters.h
  3. /// \brief Implementation of BufferedTransformation's attachment interface.
  4. #ifndef CRYPTOPP_FILTERS_H
  5. #define CRYPTOPP_FILTERS_H
  6. #include "config.h"
  7. #if CRYPTOPP_MSC_VERSION
  8. # pragma warning(push)
  9. # pragma warning(disable: 4127 4189 4231 4275 4514)
  10. #endif
  11. #include "cryptlib.h"
  12. #include "simple.h"
  13. #include "secblock.h"
  14. #include "misc.h"
  15. #include "smartptr.h"
  16. #include "queue.h"
  17. #include "algparam.h"
  18. #include "stdcpp.h"
  19. NAMESPACE_BEGIN(CryptoPP)
  20. /// \brief Implementation of BufferedTransformation's attachment interface
  21. /// \details Filter is a cornerstone of the Pipeline trinity. Data flows from
  22. /// Sources, through Filters, and then terminates in Sinks. The difference
  23. /// between a Source and Filter is a Source \a pumps data, while a Filter does
  24. /// not. The difference between a Filter and a Sink is a Filter allows an
  25. /// attached transformation, while a Sink does not.
  26. /// \details See the discussion of BufferedTransformation in cryptlib.h for
  27. /// more details.
  28. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable
  29. {
  30. public:
  31. virtual ~Filter() {}
  32. /// \name ATTACHMENT
  33. //@{
  34. /// \brief Construct a Filter
  35. /// \param attachment an optional attached transformation
  36. /// \details attachment can be NULL.
  37. Filter(BufferedTransformation *attachment = NULLPTR);
  38. /// \brief Determine if attachable
  39. /// \return true if the object allows attached transformations, false otherwise.
  40. /// \note Source and Filter offer attached transformations; while Sink does not.
  41. bool Attachable() {return true;}
  42. /// \brief Retrieve attached transformation
  43. /// \return pointer to a BufferedTransformation if there is an attached transformation, NULL otherwise.
  44. BufferedTransformation *AttachedTransformation();
  45. /// \brief Retrieve attached transformation
  46. /// \return pointer to a BufferedTransformation if there is an attached transformation, NULL otherwise.
  47. const BufferedTransformation *AttachedTransformation() const;
  48. /// \brief Replace an attached transformation
  49. /// \param newAttachment an optional attached transformation
  50. /// \details newAttachment can be a single filter, a chain of filters or NULL.
  51. /// Pass NULL to remove an existing BufferedTransformation or chain of filters
  52. void Detach(BufferedTransformation *newAttachment = NULLPTR);
  53. //@}
  54. /// \name RETRIEVAL OF ONE MESSAGE
  55. //@{
  56. // BufferedTransformation in cryptlib.h
  57. size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
  58. size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
  59. //@}
  60. /// \name SIGNALS
  61. //@{
  62. // BufferedTransformation in cryptlib.h
  63. void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1);
  64. bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
  65. bool MessageSeriesEnd(int propagation=-1, bool blocking=true);
  66. //@}
  67. protected:
  68. virtual BufferedTransformation * NewDefaultAttachment() const;
  69. void Insert(Filter *nextFilter); // insert filter after this one
  70. virtual bool ShouldPropagateMessageEnd() const {return true;}
  71. virtual bool ShouldPropagateMessageSeriesEnd() const {return true;}
  72. void PropagateInitialize(const NameValuePairs &parameters, int propagation);
  73. /// \brief Forward processed data on to attached transformation
  74. /// \param outputSite unknown, system crash between keyboard and chair...
  75. /// \param inString the byte buffer to process
  76. /// \param length the size of the string, in bytes
  77. /// \param messageEnd means how many filters to signal MessageEnd() to, including this one
  78. /// \param blocking specifies whether the object should block when processing input
  79. /// \param channel the channel to process the data
  80. /// \return the number of bytes that remain to be processed (i.e., bytes not processed).
  81. /// 0 indicates all bytes were processed.
  82. size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
  83. /// \brief Output multiple bytes that may be modified by callee.
  84. /// \param outputSite unknown, system crash between keyboard and chair...
  85. /// \param inString the byte buffer to process
  86. /// \param length the size of the string, in bytes
  87. /// \param messageEnd means how many filters to signal MessageEnd() to, including this one
  88. /// \param blocking specifies whether the object should block when processing input
  89. /// \param channel the channel to process the data
  90. /// \return the number of bytes that remain to be processed (i.e., bytes not processed).
  91. /// 0 indicates all bytes were processed.
  92. size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
  93. /// \brief Signals the end of messages to the object
  94. /// \param outputSite unknown, system crash between keyboard and chair...
  95. /// \param propagation the number of attached transformations the MessageEnd() signal should be passed
  96. /// \param blocking specifies whether the object should block when processing input
  97. /// \param channel the channel to process the data
  98. /// \return true is the MessageEnd signal was successful, false otherwise.
  99. /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
  100. /// object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
  101. bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
  102. /// \brief Flush buffered input and/or output, with signal propagation
  103. /// \param outputSite unknown, system crash between keyboard and chair...
  104. /// \param hardFlush is used to indicate whether all data should be flushed
  105. /// \param propagation the number of attached transformations the Flush() signal should be passed
  106. /// \param blocking specifies whether the object should block when processing input
  107. /// \param channel the channel to process the data
  108. /// \return true is the Flush signal was successful, false otherwise.
  109. /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
  110. /// object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
  111. /// \note Hard flushes must be used with care. It means try to process and output everything, even if
  112. /// there may not be enough data to complete the action. For example, hard flushing a HexDecoder
  113. /// would cause an error if you do it after inputing an odd number of hex encoded characters.
  114. /// \note For some types of filters, like ZlibDecompressor, hard flushes can only
  115. /// be done at "synchronization points". These synchronization points are positions in the data
  116. /// stream that are created by hard flushes on the corresponding reverse filters, in this
  117. /// example ZlibCompressor. This is useful when zlib compressed data is moved across a
  118. /// network in packets and compression state is preserved across packets, as in the SSH2 protocol.
  119. bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
  120. /// \brief Marks the end of a series of messages, with signal propagation
  121. /// \param outputSite unknown, system crash between keyboard and chair...
  122. /// \param propagation the number of attached transformations the MessageSeriesEnd() signal should be passed
  123. /// \param blocking specifies whether the object should block when processing input
  124. /// \param channel the channel to process the data
  125. /// \return true is the MessageEnd signal was successful, false otherwise.
  126. /// \details Each object that receives the signal will perform its processing, decrement
  127. /// propagation, and then pass the signal on to attached transformations if the value is not 0.
  128. /// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
  129. /// object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
  130. /// \note There should be a MessageEnd() immediately before MessageSeriesEnd().
  131. bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=DEFAULT_CHANNEL);
  132. private:
  133. member_ptr<BufferedTransformation> m_attachment;
  134. protected:
  135. size_t m_inputPosition;
  136. int m_continueAt;
  137. };
  138. /// \brief Create a working space in a BufferedTransformation
  139. struct CRYPTOPP_DLL FilterPutSpaceHelper
  140. {
  141. virtual ~FilterPutSpaceHelper() {}
  142. /// \brief Create a working space in a BufferedTransformation
  143. /// \param target BufferedTransformation for the working space
  144. /// \param channel channel for the working space
  145. /// \param minSize minimum size of the allocation, in bytes
  146. /// \param desiredSize preferred size of the allocation, in bytes
  147. /// \param bufferSize actual size of the allocation, in bytes
  148. /// \pre <tt>desiredSize >= minSize</tt> and <tt>bufferSize >= minSize</tt>.
  149. /// \details bufferSize is an IN and OUT parameter. If HelpCreatePutSpace() returns a non-NULL value, then
  150. /// bufferSize is valid and provides the size of the working space created for the caller.
  151. /// \details Internally, HelpCreatePutSpace() calls \ref BufferedTransformation::ChannelCreatePutSpace
  152. /// "ChannelCreatePutSpace()" using desiredSize. If the target returns desiredSize with a size less
  153. /// than minSize (i.e., the request could not be fulfilled), then an internal SecByteBlock
  154. /// called m_tempSpace is resized and used for the caller.
  155. byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t desiredSize, size_t &bufferSize)
  156. {
  157. CRYPTOPP_ASSERT(desiredSize >= minSize && bufferSize >= minSize);
  158. if (m_tempSpace.size() < minSize)
  159. {
  160. byte *result = target.ChannelCreatePutSpace(channel, desiredSize);
  161. if (desiredSize >= minSize)
  162. {
  163. bufferSize = desiredSize;
  164. return result;
  165. }
  166. m_tempSpace.New(bufferSize);
  167. }
  168. bufferSize = m_tempSpace.size();
  169. return m_tempSpace.begin();
  170. }
  171. /// \brief Create a working space in a BufferedTransformation
  172. /// \param target the BufferedTransformation for the working space
  173. /// \param channel channel for the working space
  174. /// \param minSize minimum size of the allocation, in bytes
  175. /// \return pointer to the created space
  176. /// \details Internally, the overload calls HelpCreatePutSpace() using minSize for missing arguments.
  177. /// \details The filter will delete the space. The caller does not need to delete the space.
  178. byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize)
  179. {return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);}
  180. /// \brief Create a working space in a BufferedTransformation
  181. /// \param target the BufferedTransformation for the working space
  182. /// \param channel channel for the working space
  183. /// \param minSize minimum size of the allocation, in bytes
  184. /// \param bufferSize the actual size of the allocation, in bytes
  185. /// \details Internally, the overload calls HelpCreatePutSpace() using minSize for missing arguments.
  186. /// \details The filter will delete the space. The caller does not need to delete the space.
  187. byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t bufferSize)
  188. {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
  189. /// \brief Temporary working space
  190. SecByteBlock m_tempSpace;
  191. };
  192. /// \brief Measure how many bytes and messages pass through the filter
  193. /// \details measure how many bytes and messages pass through the filter. The filter also serves as valve by
  194. /// maintaining a list of ranges to skip during processing.
  195. class CRYPTOPP_DLL MeterFilter : public Bufferless<Filter>
  196. {
  197. public:
  198. virtual ~MeterFilter() {}
  199. /// \brief Construct a MeterFilter
  200. /// \param attachment an optional attached transformation
  201. /// \param transparent flag indicating if the filter should function transparently
  202. /// \details attachment can be NULL. The filter is transparent by default. If the filter is
  203. /// transparent, then PutMaybeModifiable() does not process a request and always returns 0.
  204. MeterFilter(BufferedTransformation *attachment=NULLPTR, bool transparent=true)
  205. : m_transparent(transparent), m_currentMessageBytes(0), m_totalBytes(0)
  206. , m_currentSeriesMessages(0), m_totalMessages(0), m_totalMessageSeries(0)
  207. , m_begin(NULLPTR), m_length(0) {Detach(attachment); ResetMeter();}
  208. /// \brief Set or change the transparent mode of this object
  209. /// \param transparent the new transparent mode
  210. void SetTransparent(bool transparent) {m_transparent = transparent;}
  211. /// \brief Adds a range to skip during processing
  212. /// \param message the message to apply the range
  213. /// \param position the 0-based index in the current stream
  214. /// \param size the length of the range
  215. /// \param sortNow flag indicating whether the range should be sorted
  216. /// \details Internally, MeterFilter maitains a deque of ranges to skip. As messages are processed,
  217. /// ranges of bytes are skipped according to the list of ranges.
  218. void AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow = true);
  219. /// \brief Resets the meter
  220. /// \details ResetMeter() reinitializes the meter by setting counters to 0 and removing previous
  221. /// skip ranges.
  222. void ResetMeter();
  223. // BufferedTransformation in cryptlib.h
  224. void IsolatedInitialize(const NameValuePairs &parameters)
  225. {CRYPTOPP_UNUSED(parameters); ResetMeter();}
  226. /// \brief Number of bytes in the current message
  227. /// \return the number of bytes in the current message
  228. lword GetCurrentMessageBytes() const {return m_currentMessageBytes;}
  229. /// \brief Number of bytes processed by the filter
  230. /// \return the number of bytes processed by the filter
  231. lword GetTotalBytes() const {return m_totalBytes;}
  232. /// \brief Message number in the series
  233. /// \return the message number in the series
  234. unsigned int GetCurrentSeriesMessages() const {return m_currentSeriesMessages;}
  235. /// \brief Number of messages in the message series
  236. /// \return the number of messages in the message series
  237. unsigned int GetTotalMessages() const {return m_totalMessages;}
  238. /// \brief Number of messages processed by the filter
  239. /// \return the number of messages processed by the filter
  240. unsigned int GetTotalMessageSeries() const {return m_totalMessageSeries;}
  241. // BufferedTransformation in cryptlib.h
  242. byte * CreatePutSpace(size_t &size) {return AttachedTransformation()->CreatePutSpace(size);}
  243. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
  244. size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking);
  245. bool IsolatedMessageSeriesEnd(bool blocking);
  246. private:
  247. size_t PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable);
  248. bool ShouldPropagateMessageEnd() const {return m_transparent;}
  249. bool ShouldPropagateMessageSeriesEnd() const {return m_transparent;}
  250. struct MessageRange
  251. {
  252. inline bool operator<(const MessageRange &b) const // BCB2006 workaround: this has to be a member function
  253. {return message < b.message || (message == b.message && position < b.position);}
  254. unsigned int message; lword position; lword size;
  255. };
  256. bool m_transparent;
  257. lword m_currentMessageBytes, m_totalBytes;
  258. unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries;
  259. std::deque<MessageRange> m_rangesToSkip;
  260. byte *m_begin;
  261. size_t m_length;
  262. };
  263. /// \brief A transparent MeterFilter
  264. /// \sa MeterFilter, OpaqueFilter
  265. class CRYPTOPP_DLL TransparentFilter : public MeterFilter
  266. {
  267. public:
  268. /// \brief Construct a TransparentFilter
  269. /// \param attachment an optional attached transformation
  270. TransparentFilter(BufferedTransformation *attachment=NULLPTR) : MeterFilter(attachment, true) {}
  271. };
  272. /// \brief A non-transparent MeterFilter
  273. /// \sa MeterFilter, TransparentFilter
  274. class CRYPTOPP_DLL OpaqueFilter : public MeterFilter
  275. {
  276. public:
  277. /// \brief Construct an OpaqueFilter
  278. /// \param attachment an optional attached transformation
  279. OpaqueFilter(BufferedTransformation *attachment=NULLPTR) : MeterFilter(attachment, false) {}
  280. };
  281. /// \brief Divides an input stream into discrete blocks
  282. /// \details FilterWithBufferedInput divides the input stream into a first block, a number of
  283. /// middle blocks, and a last block. First and last blocks are optional, and middle blocks may
  284. /// be a stream instead (i.e. <tt>blockSize == 1</tt>).
  285. /// \sa AuthenticatedEncryptionFilter, AuthenticatedDecryptionFilter, HashVerificationFilter,
  286. /// SignatureVerificationFilter, StreamTransformationFilter
  287. class CRYPTOPP_DLL FilterWithBufferedInput : public Filter
  288. {
  289. public:
  290. virtual ~FilterWithBufferedInput() {}
  291. /// \brief Construct a FilterWithBufferedInput with an attached transformation
  292. /// \param attachment an attached transformation
  293. FilterWithBufferedInput(BufferedTransformation *attachment);
  294. /// \brief Construct a FilterWithBufferedInput with an attached transformation
  295. /// \param firstSize the size of the first block
  296. /// \param blockSize the size of middle blocks
  297. /// \param lastSize the size of the last block
  298. /// \param attachment an attached transformation
  299. /// \details firstSize and lastSize may be 0. blockSize must be at least 1.
  300. FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment);
  301. void IsolatedInitialize(const NameValuePairs &parameters);
  302. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
  303. {
  304. return PutMaybeModifiable(const_cast<byte *>(inString), length, messageEnd, blocking, false);
  305. }
  306. size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
  307. {
  308. return PutMaybeModifiable(inString, length, messageEnd, blocking, true);
  309. }
  310. /// \brief Flushes data buffered by this object, without signal propagation
  311. /// \param hardFlush indicates whether all data should be flushed
  312. /// \param blocking specifies whether the object should block when processing input
  313. /// \return true if the Flush was successful, false otherwise
  314. /// \details IsolatedFlush() calls ForceNextPut() if hardFlush is true
  315. /// \note hardFlush must be used with care
  316. bool IsolatedFlush(bool hardFlush, bool blocking);
  317. /// \brief Flushes data buffered by this object
  318. /// \details The input buffer may contain more than blockSize bytes if <tt>lastSize != 0</tt>.
  319. /// ForceNextPut() forces a call to NextPut() if this is the case.
  320. void ForceNextPut();
  321. protected:
  322. virtual bool DidFirstPut() const {return m_firstInputDone;}
  323. virtual size_t GetFirstPutSize() const {return m_firstSize;}
  324. virtual size_t GetBlockPutSize() const {return m_blockSize;}
  325. virtual size_t GetLastPutSize() const {return m_lastSize;}
  326. virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
  327. {CRYPTOPP_UNUSED(parameters); CRYPTOPP_UNUSED(firstSize); CRYPTOPP_UNUSED(blockSize); CRYPTOPP_UNUSED(lastSize); InitializeDerived(parameters);}
  328. virtual void InitializeDerived(const NameValuePairs &parameters)
  329. {CRYPTOPP_UNUSED(parameters);}
  330. // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize)
  331. // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received)).
  332. // inString is m_firstSize in length.
  333. virtual void FirstPut(const byte *inString) =0;
  334. // NextPut() is called if totalLength >= firstSize+blockSize+lastSize
  335. virtual void NextPutSingle(const byte *inString)
  336. {CRYPTOPP_UNUSED(inString); CRYPTOPP_ASSERT(false);}
  337. // Same as NextPut() except length can be a multiple of blockSize
  338. // Either NextPut() or NextPutMultiple() must be overridden
  339. virtual void NextPutMultiple(const byte *inString, size_t length);
  340. // Same as NextPutMultiple(), but inString can be modified
  341. virtual void NextPutModifiable(byte *inString, size_t length)
  342. {NextPutMultiple(inString, length);}
  343. /// \brief Input the last block of data
  344. /// \param inString the input byte buffer
  345. /// \param length the size of the input buffer, in bytes
  346. /// \details LastPut() processes the last block of data and signals attached filters to do the same.
  347. /// LastPut() is always called. The pseudo algorithm for the logic is:
  348. /// <pre>
  349. /// if totalLength < firstSize then length == totalLength
  350. /// else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
  351. /// else lastSize <= length < lastSize+blockSize
  352. /// </pre>
  353. virtual void LastPut(const byte *inString, size_t length) =0;
  354. virtual void FlushDerived() {}
  355. protected:
  356. size_t PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable);
  357. void NextPutMaybeModifiable(byte *inString, size_t length, bool modifiable)
  358. {
  359. if (modifiable) NextPutModifiable(inString, length);
  360. else NextPutMultiple(inString, length);
  361. }
  362. // This function should no longer be used, put this here to cause a compiler error
  363. // if someone tries to override NextPut().
  364. virtual int NextPut(const byte *inString, size_t length)
  365. {CRYPTOPP_UNUSED(inString); CRYPTOPP_UNUSED(length); CRYPTOPP_ASSERT(false); return 0;}
  366. class BlockQueue
  367. {
  368. public:
  369. void ResetQueue(size_t blockSize, size_t maxBlocks);
  370. byte *GetBlock();
  371. byte *GetContigousBlocks(size_t &numberOfBytes);
  372. size_t GetAll(byte *outString);
  373. void Put(const byte *inString, size_t length);
  374. size_t CurrentSize() const {return m_size;}
  375. size_t MaxSize() const {return m_buffer.size();}
  376. private:
  377. SecByteBlock m_buffer;
  378. size_t m_blockSize, m_maxBlocks, m_size;
  379. byte *m_begin;
  380. };
  381. size_t m_firstSize, m_blockSize, m_lastSize;
  382. bool m_firstInputDone;
  383. BlockQueue m_queue;
  384. };
  385. /// \brief A filter that buffers input using a ByteQueue
  386. /// \details FilterWithInputQueue will buffer input using a ByteQueue. When the filter receives
  387. /// a \ref BufferedTransformation::MessageEnd() "MessageEnd()" signal it will pass the data
  388. /// on to its attached transformation.
  389. class CRYPTOPP_DLL FilterWithInputQueue : public Filter
  390. {
  391. public:
  392. virtual ~FilterWithInputQueue() {}
  393. /// \brief Construct a FilterWithInputQueue
  394. /// \param attachment an optional attached transformation
  395. FilterWithInputQueue(BufferedTransformation *attachment=NULLPTR) : Filter(attachment) {}
  396. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
  397. {
  398. if (!blocking)
  399. throw BlockingInputOnly("FilterWithInputQueue");
  400. m_inQueue.Put(inString, length);
  401. if (messageEnd)
  402. {
  403. IsolatedMessageEnd(blocking);
  404. Output(0, NULLPTR, 0, messageEnd, blocking);
  405. }
  406. return 0;
  407. }
  408. protected:
  409. virtual bool IsolatedMessageEnd(bool blocking) =0;
  410. void IsolatedInitialize(const NameValuePairs &parameters)
  411. {CRYPTOPP_UNUSED(parameters); m_inQueue.Clear();}
  412. ByteQueue m_inQueue;
  413. };
  414. /// \struct BlockPaddingSchemeDef
  415. /// \brief Padding schemes used for block ciphers
  416. /// \since Crypto++ 5.0
  417. struct BlockPaddingSchemeDef
  418. {
  419. /// \enum BlockPaddingScheme
  420. /// \brief Padding schemes used for block ciphers.
  421. /// \details DEFAULT_PADDING means PKCS_PADDING if <tt>cipher.MandatoryBlockSize() > 1 &&
  422. /// cipher.MinLastBlockSize() == 0</tt>, which holds for ECB or CBC mode. Otherwise,
  423. /// NO_PADDING for modes like OFB, CFB, CTR, CBC-CTS.
  424. /// \sa <A HREF="http://www.weidai.com/scan-mirror/csp.html">Block Cipher Padding</A> for
  425. /// additional details.
  426. /// \since Crypto++ 5.0
  427. enum BlockPaddingScheme {
  428. /// \brief No padding added to a block
  429. /// \since Crypto++ 5.0
  430. NO_PADDING,
  431. /// \brief 0's padding added to a block
  432. /// \since Crypto++ 5.0
  433. ZEROS_PADDING,
  434. /// \brief PKCS padding added to a block
  435. /// \since Crypto++ 5.0
  436. PKCS_PADDING,
  437. /// \brief 1 and 0's padding added to a block
  438. /// \since Crypto++ 5.0
  439. ONE_AND_ZEROS_PADDING,
  440. /// \brief W3C padding added to a block
  441. /// \sa <A HREF="http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html">XML
  442. /// Encryption Syntax and Processing</A>
  443. /// \since Crypto++ 6.0
  444. W3C_PADDING,
  445. /// \brief Default padding scheme
  446. /// \since Crypto++ 5.0
  447. DEFAULT_PADDING
  448. };
  449. };
  450. /// \brief Filter wrapper for StreamTransformation
  451. /// \details StreamTransformationFilter() is a filter wrapper for StreamTransformation(). It is used when
  452. /// pipelining data for stream ciphers and confidentiality-only block ciphers. The filter will optionally
  453. /// handle padding and unpadding when needed. If you are using an authenticated encryption mode of operation,
  454. /// then use AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter()
  455. /// \since Crypto++ 5.0
  456. class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef, private FilterPutSpaceHelper
  457. {
  458. public:
  459. virtual ~StreamTransformationFilter() {}
  460. /// \brief Construct a StreamTransformationFilter
  461. /// \param c reference to a StreamTransformation
  462. /// \param attachment an optional attached transformation
  463. /// \param padding the \ref BlockPaddingSchemeDef "padding scheme"
  464. /// \details This constructor creates a StreamTransformationFilter() for stream ciphers and
  465. /// confidentiality-only block cipher modes of operation. If you are using an authenticated
  466. /// encryption mode of operation, then use either AuthenticatedEncryptionFilter() or
  467. /// AuthenticatedDecryptionFilter().
  468. /// \sa AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter()
  469. StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULLPTR, BlockPaddingScheme padding = DEFAULT_PADDING);
  470. std::string AlgorithmName() const {return m_cipher.AlgorithmName();}
  471. protected:
  472. friend class AuthenticatedEncryptionFilter;
  473. friend class AuthenticatedDecryptionFilter;
  474. /// \brief Construct a StreamTransformationFilter
  475. /// \param c reference to a StreamTransformation
  476. /// \param attachment an optional attached transformation
  477. /// \param padding the \ref BlockPaddingSchemeDef "padding scheme"
  478. /// \param authenticated flag indicating whether the filter should allow authenticated encryption schemes
  479. /// \details This constructor is used for authenticated encryption mode of operation and by
  480. /// AuthenticatedEncryptionFilter() and AuthenticatedDecryptionFilter().
  481. StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated);
  482. void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
  483. void FirstPut(const byte *inString);
  484. void NextPutMultiple(const byte *inString, size_t length);
  485. void NextPutModifiable(byte *inString, size_t length);
  486. void LastPut(const byte *inString, size_t length);
  487. static size_t LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding);
  488. StreamTransformation &m_cipher;
  489. BlockPaddingScheme m_padding;
  490. unsigned int m_mandatoryBlockSize;
  491. unsigned int m_optimalBufferSize;
  492. unsigned int m_reservedBufferSize;
  493. bool m_isSpecial;
  494. };
  495. /// \brief Filter wrapper for HashTransformation
  496. /// \since Crypto++ 1.0
  497. class CRYPTOPP_DLL HashFilter : public Bufferless<Filter>, private FilterPutSpaceHelper
  498. {
  499. public:
  500. virtual ~HashFilter() {}
  501. /// \brief Construct a HashFilter
  502. /// \param hm reference to a HashTransformation
  503. /// \param attachment an optional attached transformation
  504. /// \param putMessage flag indicating whether the original message should be passed to an attached transformation
  505. /// \param truncatedDigestSize the size of the digest
  506. /// \param messagePutChannel the channel on which the message should be output
  507. /// \param hashPutChannel the channel on which the digest should be output
  508. HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULLPTR, bool putMessage=false, int truncatedDigestSize=-1, const std::string &messagePutChannel=DEFAULT_CHANNEL, const std::string &hashPutChannel=DEFAULT_CHANNEL);
  509. std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
  510. void IsolatedInitialize(const NameValuePairs &parameters);
  511. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
  512. byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);}
  513. private:
  514. HashTransformation &m_hashModule;
  515. bool m_putMessage;
  516. unsigned int m_digestSize;
  517. byte *m_space;
  518. std::string m_messagePutChannel, m_hashPutChannel;
  519. };
  520. /// \brief Filter wrapper for HashTransformation
  521. /// \since Crypto++ 4.0
  522. class CRYPTOPP_DLL HashVerificationFilter : public FilterWithBufferedInput
  523. {
  524. public:
  525. virtual ~HashVerificationFilter() {}
  526. /// \brief Exception thrown when a data integrity check failure is encountered
  527. class HashVerificationFailed : public Exception
  528. {
  529. public:
  530. HashVerificationFailed()
  531. : Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerificationFilter: message hash or MAC not valid") {}
  532. };
  533. /// \enum Flags
  534. /// \brief Flags controlling filter behavior.
  535. /// \details The flags are a bitmask and can be OR'd together.
  536. enum Flags {
  537. /// \brief The hash is at the end of the message (i.e., concatenation of message+hash)
  538. HASH_AT_END=0,
  539. /// \brief The hash is at the beginning of the message (i.e., concatenation of hash+message)
  540. HASH_AT_BEGIN=1,
  541. /// \brief The message should be passed to an attached transformation
  542. PUT_MESSAGE=2,
  543. /// \brief The hash should be passed to an attached transformation
  544. PUT_HASH=4,
  545. /// \brief The result of the verification should be passed to an attached transformation
  546. PUT_RESULT=8,
  547. /// \brief The filter should throw a HashVerificationFailed if a failure is encountered
  548. THROW_EXCEPTION=16,
  549. /// \brief Default flags using HASH_AT_BEGIN and PUT_RESULT
  550. DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT
  551. };
  552. /// \brief Construct a HashVerificationFilter
  553. /// \param hm reference to a HashTransformation
  554. /// \param attachment an optional attached transformation
  555. /// \param flags flags indicating behaviors for the filter
  556. /// \param truncatedDigestSize the size of the digest
  557. /// \details <tt>truncatedDigestSize = -1</tt> indicates \ref HashTransformation::DigestSize() "DigestSize" should be used.
  558. HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULLPTR, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1);
  559. std::string AlgorithmName() const {return m_hashModule.AlgorithmName();}
  560. bool GetLastResult() const {return m_verified;}
  561. protected:
  562. void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
  563. void FirstPut(const byte *inString);
  564. void NextPutMultiple(const byte *inString, size_t length);
  565. void LastPut(const byte *inString, size_t length);
  566. private:
  567. friend class AuthenticatedDecryptionFilter;
  568. HashTransformation &m_hashModule;
  569. word32 m_flags;
  570. unsigned int m_digestSize;
  571. bool m_verified;
  572. SecByteBlock m_expectedHash;
  573. };
  574. /// \brief Filter wrapper for encrypting with AuthenticatedSymmetricCipher
  575. /// \details AuthenticatedEncryptionFilter() is a wrapper for encrypting with
  576. /// AuthenticatedSymmetricCipher(), optionally handling padding/unpadding when needed.
  577. /// \details AuthenticatedDecryptionFilter() for Crypto++ 8.2 and earlier
  578. /// had a bug where a FileSource() would cause an exception, but a StringSource()
  579. /// was OK. Also see <A HREF=
  580. /// "https://github.com/weidai11/cryptopp/issues/817">Issue 817</A> and <A HREF=
  581. /// "https://github.com/weidai11/cryptopp/commit/ff110c6e183e">Commit ff110c6e183e</A>.
  582. /// \sa AuthenticatedSymmetricCipher, AuthenticatedDecryptionFilter, EAX, CCM, GCM,
  583. /// and <A HREF="https://www.cryptopp.com/wiki/AadSource">AadSource</A> on the
  584. /// Crypto++ wiki.
  585. /// \since Crypto++ 5.6.0
  586. class CRYPTOPP_DLL AuthenticatedEncryptionFilter : public StreamTransformationFilter
  587. {
  588. public:
  589. virtual ~AuthenticatedEncryptionFilter() {}
  590. /// \brief Construct a AuthenticatedEncryptionFilter
  591. /// \param c reference to a AuthenticatedSymmetricCipher
  592. /// \param attachment an optional attached transformation
  593. /// \param putAAD flag indicating whether the AAD should be passed to an attached transformation
  594. /// \param truncatedDigestSize the size of the digest
  595. /// \param macChannel the channel on which the MAC should be output
  596. /// \param padding the \ref BlockPaddingSchemeDef "padding scheme"
  597. /// \details <tt>truncatedDigestSize = -1</tt> indicates \ref HashTransformation::DigestSize() "DigestSize" should be used.
  598. /// \since Crypto++ 5.6.0
  599. AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULLPTR, bool putAAD=false, int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL, BlockPaddingScheme padding = DEFAULT_PADDING);
  600. void IsolatedInitialize(const NameValuePairs &parameters);
  601. byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
  602. size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
  603. /// \brief Input the last block of data
  604. /// \param inString the input byte buffer
  605. /// \param length the size of the input buffer, in bytes
  606. /// \details LastPut() processes the last block of data and signals attached filters to do the same.
  607. /// LastPut() is always called. The pseudo algorithm for the logic is:
  608. /// <pre>
  609. /// if totalLength < firstSize then length == totalLength
  610. /// else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
  611. /// else lastSize <= length < lastSize+blockSize
  612. /// </pre>
  613. void LastPut(const byte *inString, size_t length);
  614. protected:
  615. HashFilter m_hf;
  616. };
  617. /// \brief Filter wrapper for decrypting with AuthenticatedSymmetricCipher
  618. /// \details AuthenticatedDecryptionFilter() is a wrapper for decrypting with
  619. /// AuthenticatedSymmetricCipher(), optionally handling padding/unpadding when
  620. /// needed.
  621. /// \details AuthenticatedDecryptionFilter() for Crypto++ 8.2 and earlier
  622. /// had a bug where a FileSource() would cause an exception, but a StringSource()
  623. /// was OK. Also see <A HREF=
  624. /// "https://github.com/weidai11/cryptopp/issues/817">Issue 817</A> and <A HREF=
  625. /// "https://github.com/weidai11/cryptopp/commit/ff110c6e183e">Commit ff110c6e183e</A>.
  626. /// \sa AuthenticatedSymmetricCipher, AuthenticatedEncryptionFilter, EAX, CCM, GCM,
  627. /// and <A HREF="https://www.cryptopp.com/wiki/AadSource">AadSource</A> on the
  628. /// Crypto++ wiki.
  629. /// \since Crypto++ 5.6.0
  630. class CRYPTOPP_DLL AuthenticatedDecryptionFilter : public FilterWithBufferedInput, public BlockPaddingSchemeDef
  631. {
  632. public:
  633. /// \enum Flags
  634. /// \brief Flags controlling filter behavior.
  635. /// \details The flags are a bitmask and can be OR'd together.
  636. enum Flags {
  637. /// \brief The MAC is at the end of the message (i.e., concatenation of message+mac)
  638. MAC_AT_END=0,
  639. /// \brief The MAC is at the beginning of the message (i.e., concatenation of mac+message)
  640. MAC_AT_BEGIN=1,
  641. /// \brief The filter should throw a HashVerificationFailed if a failure is encountered
  642. THROW_EXCEPTION=16,
  643. /// \brief Default flags using THROW_EXCEPTION
  644. DEFAULT_FLAGS = THROW_EXCEPTION
  645. };
  646. virtual ~AuthenticatedDecryptionFilter() {}
  647. /// \brief Construct a AuthenticatedDecryptionFilter
  648. /// \param c reference to a AuthenticatedSymmetricCipher
  649. /// \param attachment an optional attached transformation
  650. /// \param flags flags indicating behaviors for the filter
  651. /// \param truncatedDigestSize the size of the digest
  652. /// \param padding the \ref BlockPaddingSchemeDef "padding scheme"
  653. /// \details Additional authenticated data should be given in channel "AAD".
  654. /// \details <tt>truncatedDigestSize = -1</tt> indicates \ref HashTransformation::DigestSize() "DigestSize" should be used.
  655. /// \since Crypto++ 5.6.0
  656. AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment = NULLPTR, word32 flags = DEFAULT_FLAGS, int truncatedDigestSize=-1, BlockPaddingScheme padding = DEFAULT_PADDING);
  657. std::string AlgorithmName() const {return m_hashVerifier.AlgorithmName();}
  658. byte * ChannelCreatePutSpace(const std::string &channel, size_t &size);
  659. size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking);
  660. size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
  661. { return ChannelPut2(channel, begin, length, messageEnd, blocking); }
  662. /// \brief Get verifier result
  663. /// \return true if the digest on the previosus message was valid, false otherwise
  664. bool GetLastResult() const {return m_hashVerifier.GetLastResult();}
  665. protected:
  666. void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
  667. void FirstPut(const byte *inString);
  668. void NextPutMultiple(const byte *inString, size_t length);
  669. /// \brief Input the last block of data
  670. /// \param inString the input byte buffer
  671. /// \param length the size of the input buffer, in bytes
  672. /// \details LastPut() processes the last block of data and signals attached filters to do the same.
  673. /// LastPut() is always called. The pseudo algorithm for the logic is:
  674. /// <pre>
  675. /// if totalLength < firstSize then length == totalLength
  676. /// else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
  677. /// else lastSize <= length < lastSize+blockSize
  678. /// </pre>
  679. void LastPut(const byte *inString, size_t length);
  680. HashVerificationFilter m_hashVerifier;
  681. StreamTransformationFilter m_streamFilter;
  682. };
  683. /// \brief Filter wrapper for PK_Signer
  684. /// \since Crypto++ 4.0
  685. class CRYPTOPP_DLL SignerFilter : public Unflushable<Filter>
  686. {
  687. public:
  688. virtual ~SignerFilter() {}
  689. /// \brief Construct a SignerFilter
  690. /// \param rng a RandomNumberGenerator derived class
  691. /// \param signer a PK_Signer derived class
  692. /// \param attachment an optional attached transformation
  693. /// \param putMessage flag indicating whether the original message should be passed to an attached transformation
  694. SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULLPTR, bool putMessage=false)
  695. : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator(rng)), m_putMessage(putMessage) {Detach(attachment);}
  696. std::string AlgorithmName() const {return m_signer.AlgorithmName();}
  697. void IsolatedInitialize(const NameValuePairs &parameters);
  698. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
  699. private:
  700. RandomNumberGenerator &m_rng;
  701. const PK_Signer &m_signer;
  702. member_ptr<PK_MessageAccumulator> m_messageAccumulator;
  703. bool m_putMessage;
  704. SecByteBlock m_buf;
  705. };
  706. /// \brief Filter wrapper for PK_Verifier
  707. /// \details This filter was formerly named <tt>VerifierFilter</tt>. The name changed at Crypto++ 5.0.
  708. /// \since Crypto++ 4.0
  709. class CRYPTOPP_DLL SignatureVerificationFilter : public FilterWithBufferedInput
  710. {
  711. public:
  712. /// \brief Exception thrown when an invalid signature is encountered
  713. class SignatureVerificationFailed : public Exception
  714. {
  715. public:
  716. SignatureVerificationFailed()
  717. : Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {}
  718. };
  719. /// \enum Flags
  720. /// \brief Flags controlling filter behavior.
  721. /// \details The flags are a bitmask and can be OR'd together.
  722. enum Flags {
  723. /// \brief The signature is at the end of the message (i.e., concatenation of message+signature)
  724. SIGNATURE_AT_END=0,
  725. /// \brief The signature is at the beginning of the message (i.e., concatenation of signature+message)
  726. SIGNATURE_AT_BEGIN=1,
  727. /// \brief The message should be passed to an attached transformation
  728. PUT_MESSAGE=2,
  729. /// \brief The signature should be passed to an attached transformation
  730. PUT_SIGNATURE=4,
  731. /// \brief The result of the verification should be passed to an attached transformation
  732. PUT_RESULT=8,
  733. /// \brief The filter should throw a HashVerificationFailed if a failure is encountered
  734. THROW_EXCEPTION=16,
  735. /// \brief Default flags using SIGNATURE_AT_BEGIN and PUT_RESULT
  736. DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT
  737. };
  738. virtual ~SignatureVerificationFilter() {}
  739. /// \brief Construct a SignatureVerificationFilter
  740. /// \param verifier a PK_Verifier derived class
  741. /// \param attachment an optional attached transformation
  742. /// \param flags flags indicating behaviors for the filter
  743. SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULLPTR, word32 flags = DEFAULT_FLAGS);
  744. std::string AlgorithmName() const {return m_verifier.AlgorithmName();}
  745. /// \brief Retrieves the result of the last verification
  746. /// \return true if the signature on the previosus message was valid, false otherwise
  747. bool GetLastResult() const {return m_verified;}
  748. protected:
  749. void InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize);
  750. void FirstPut(const byte *inString);
  751. void NextPutMultiple(const byte *inString, size_t length);
  752. void LastPut(const byte *inString, size_t length);
  753. private:
  754. const PK_Verifier &m_verifier;
  755. member_ptr<PK_MessageAccumulator> m_messageAccumulator;
  756. word32 m_flags;
  757. SecByteBlock m_signature;
  758. bool m_verified;
  759. };
  760. /// \brief Redirect input to another BufferedTransformation without owning it
  761. /// \since Crypto++ 4.0
  762. class CRYPTOPP_DLL Redirector : public CustomSignalPropagation<Sink>
  763. {
  764. public:
  765. /// \enum Behavior
  766. /// \brief Controls signal propagation behavior
  767. enum Behavior
  768. {
  769. /// \brief Pass data only
  770. DATA_ONLY = 0x00,
  771. /// \brief Pass signals
  772. PASS_SIGNALS = 0x01,
  773. /// \brief Pass wait events
  774. PASS_WAIT_OBJECTS = 0x02,
  775. /// \brief Pass everything
  776. /// \details PASS_EVERYTHING is default
  777. PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS
  778. };
  779. virtual ~Redirector() {}
  780. /// \brief Construct a Redirector
  781. Redirector() : m_target(NULLPTR), m_behavior(PASS_EVERYTHING) {}
  782. /// \brief Construct a Redirector
  783. /// \param target the destination BufferedTransformation
  784. /// \param behavior Behavior "flags" specifying signal propagation
  785. Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING)
  786. : m_target(&target), m_behavior(behavior) {}
  787. /// \brief Redirect input to another BufferedTransformation
  788. /// \param target the destination BufferedTransformation
  789. void Redirect(BufferedTransformation &target) {m_target = &target;}
  790. /// \brief Stop redirecting input
  791. void StopRedirection() {m_target = NULLPTR;}
  792. /// \brief Retrieve signal propagation behavior
  793. /// \return the current signal propagation behavior
  794. Behavior GetBehavior() {return static_cast<Behavior>(m_behavior);}
  795. /// \brief Set signal propagation behavior
  796. /// \param behavior the new signal propagation behavior
  797. void SetBehavior(Behavior behavior) {m_behavior=behavior;}
  798. /// \brief Retrieve signal propagation behavior
  799. /// \return true if the Redirector passes signals, false otherwise.
  800. bool GetPassSignals() const {return (m_behavior & PASS_SIGNALS) != 0;}
  801. /// \brief Set signal propagation behavior
  802. /// \param pass flag indicating if the Redirector should pass signals
  803. void SetPassSignals(bool pass) { if (pass) m_behavior |= PASS_SIGNALS; else m_behavior &= ~static_cast<word32>(PASS_SIGNALS); }
  804. /// \brief Retrieve signal propagation behavior
  805. /// \return true if the Redirector passes wait objects, false otherwise.
  806. bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;}
  807. /// \brief Set signal propagation behavior
  808. /// \param pass flag indicating if the Redirector should pass wait objects
  809. void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~static_cast<word32>(PASS_WAIT_OBJECTS); }
  810. bool CanModifyInput() const
  811. {return m_target ? m_target->CanModifyInput() : false;}
  812. void Initialize(const NameValuePairs &parameters, int propagation);
  813. byte * CreatePutSpace(size_t &size)
  814. {
  815. if (m_target)
  816. return m_target->CreatePutSpace(size);
  817. else
  818. {
  819. size = 0;
  820. return NULLPTR;
  821. }
  822. }
  823. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
  824. {return m_target ? m_target->Put2(inString, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
  825. bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
  826. {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;}
  827. bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
  828. {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;}
  829. byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
  830. {
  831. if (m_target)
  832. return m_target->ChannelCreatePutSpace(channel, size);
  833. else
  834. {
  835. size = 0;
  836. return NULLPTR;
  837. }
  838. }
  839. size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
  840. {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
  841. size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
  842. {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;}
  843. bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
  844. {return m_target && GetPassSignals() ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
  845. bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
  846. {return m_target && GetPassSignals() ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
  847. unsigned int GetMaxWaitObjectCount() const
  848. { return m_target && GetPassWaitObjects() ? m_target->GetMaxWaitObjectCount() : 0; }
  849. void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
  850. { if (m_target && GetPassWaitObjects()) m_target->GetWaitObjects(container, callStack); }
  851. private:
  852. BufferedTransformation *m_target;
  853. word32 m_behavior;
  854. };
  855. /// \brief Filter class that is a proxy for a sink
  856. /// \details Used By ProxyFilter
  857. /// \since Crypto++ 4.0
  858. class CRYPTOPP_DLL OutputProxy : public CustomSignalPropagation<Sink>
  859. {
  860. public:
  861. virtual ~OutputProxy() {}
  862. /// \brief Construct an OutputProxy
  863. /// \param owner the owning transformation
  864. /// \param passSignal flag indicating if signals should be passed
  865. OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {}
  866. /// \brief Retrieve passSignal flag
  867. /// \return flag indicating if signals should be passed
  868. bool GetPassSignal() const {return m_passSignal;}
  869. /// \brief Set passSignal flag
  870. /// \param passSignal flag indicating if signals should be passed
  871. void SetPassSignal(bool passSignal) {m_passSignal = passSignal;}
  872. byte * CreatePutSpace(size_t &size)
  873. {return m_owner.AttachedTransformation()->CreatePutSpace(size);}
  874. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
  875. {return m_owner.AttachedTransformation()->Put2(inString, length, m_passSignal ? messageEnd : 0, blocking);}
  876. size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
  877. {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);}
  878. void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
  879. {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);}
  880. bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
  881. {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;}
  882. bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
  883. {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;}
  884. byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
  885. {return m_owner.AttachedTransformation()->ChannelCreatePutSpace(channel, size);}
  886. size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
  887. {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
  888. size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
  889. {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);}
  890. bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true)
  891. {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;}
  892. bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
  893. {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;}
  894. private:
  895. BufferedTransformation &m_owner;
  896. bool m_passSignal;
  897. };
  898. /// \brief Base class for Filter classes that are proxies for a chain of other filters
  899. /// \since Crypto++ 4.0
  900. class CRYPTOPP_DLL ProxyFilter : public FilterWithBufferedInput
  901. {
  902. public:
  903. virtual ~ProxyFilter() {}
  904. /// \brief Construct a ProxyFilter
  905. /// \param filter an output filter
  906. /// \param firstSize the first Put size
  907. /// \param lastSize the last Put size
  908. /// \param attachment an attached transformation
  909. ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment);
  910. bool IsolatedFlush(bool hardFlush, bool blocking);
  911. /// \brief Sets the OutputProxy filter
  912. /// \param filter an OutputProxy filter
  913. void SetFilter(Filter *filter);
  914. void NextPutMultiple(const byte *s, size_t len);
  915. void NextPutModifiable(byte *inString, size_t length);
  916. protected:
  917. member_ptr<BufferedTransformation> m_filter;
  918. };
  919. /// \brief Proxy filter that doesn't modify the underlying filter's input or output
  920. /// \since Crypto++ 5.0
  921. class CRYPTOPP_DLL SimpleProxyFilter : public ProxyFilter
  922. {
  923. public:
  924. /// \brief Construct a SimpleProxyFilter
  925. /// \param filter an output filter
  926. /// \param attachment an attached transformation
  927. SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment)
  928. : ProxyFilter(filter, 0, 0, attachment) {}
  929. void FirstPut(const byte * inString)
  930. {CRYPTOPP_UNUSED(inString);}
  931. /// \brief Input the last block of data
  932. /// \param inString the input byte buffer
  933. /// \param length the size of the input buffer, in bytes
  934. /// \details LastPut() processes the last block of data and signals attached filters to do the same.
  935. /// LastPut() is always called. The pseudo algorithm for the logic is:
  936. /// <pre>
  937. /// if totalLength < firstSize then length == totalLength
  938. /// else if totalLength <= firstSize+lastSize then length == totalLength-firstSize
  939. /// else lastSize <= length < lastSize+blockSize
  940. /// </pre>
  941. void LastPut(const byte *inString, size_t length)
  942. {CRYPTOPP_UNUSED(inString), CRYPTOPP_UNUSED(length); m_filter->MessageEnd();}
  943. };
  944. /// \brief Filter wrapper for PK_Encryptor
  945. /// \details PK_DecryptorFilter is a proxy for the filter created by PK_Encryptor::CreateEncryptionFilter.
  946. /// This class provides symmetry with VerifierFilter.
  947. /// \since Crypto++ 5.0
  948. class CRYPTOPP_DLL PK_EncryptorFilter : public SimpleProxyFilter
  949. {
  950. public:
  951. /// \brief Construct a PK_EncryptorFilter
  952. /// \param rng a RandomNumberGenerator derived class
  953. /// \param encryptor a PK_Encryptor derived class
  954. /// \param attachment an optional attached transformation
  955. PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULLPTR)
  956. : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {}
  957. };
  958. /// \brief Filter wrapper for PK_Decryptor
  959. /// \details PK_DecryptorFilter is a proxy for the filter created by PK_Decryptor::CreateDecryptionFilter.
  960. /// This class provides symmetry with SignerFilter.
  961. /// \since Crypto++ 5.0
  962. class CRYPTOPP_DLL PK_DecryptorFilter : public SimpleProxyFilter
  963. {
  964. public:
  965. /// \brief Construct a PK_DecryptorFilter
  966. /// \param rng a RandomNumberGenerator derived class
  967. /// \param decryptor a PK_Decryptor derived class
  968. /// \param attachment an optional attached transformation
  969. PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULLPTR)
  970. : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {}
  971. };
  972. /// \brief Append input to a string object
  973. /// \tparam T std::basic_string<char> type
  974. /// \details StringSinkTemplate is a StringSinkTemplate typedef
  975. /// \since Crypto++ 5.0
  976. template <class T>
  977. class StringSinkTemplate : public Bufferless<Sink>
  978. {
  979. public:
  980. typedef typename T::value_type value_type;
  981. virtual ~StringSinkTemplate() {}
  982. /// \brief Construct a StringSinkTemplate
  983. /// \param output std::basic_string<char> or std::vector<byte> type
  984. StringSinkTemplate(T &output)
  985. : m_output(&output) {CRYPTOPP_ASSERT(sizeof(value_type)==1);}
  986. void IsolatedInitialize(const NameValuePairs &parameters)
  987. {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");}
  988. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
  989. {
  990. CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
  991. if (length > 0)
  992. {
  993. typename T::size_type size = m_output->size();
  994. if (length < size && size + length > m_output->capacity())
  995. m_output->reserve(2*size);
  996. m_output->insert(m_output->end(), (const value_type *)inString, (const value_type *)inString+length);
  997. }
  998. return 0;
  999. }
  1000. private:
  1001. T *m_output;
  1002. };
  1003. /// \brief Append input to a string object
  1004. /// \details StringSink is a typedef for StringSinkTemplate<std::string>.
  1005. /// \sa ArraySink, ArrayXorSink
  1006. /// \since Crypto++ 4.0
  1007. DOCUMENTED_TYPEDEF(StringSinkTemplate<std::string>, StringSink);
  1008. CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>;
  1009. /// \brief Append input to a std::vector<byte> object
  1010. /// \details VectorSink is a typedef for StringSinkTemplate<std::vector<byte> >.
  1011. /// \since Crypto++ 8.0
  1012. DOCUMENTED_TYPEDEF(StringSinkTemplate<std::vector<byte> >, VectorSink);
  1013. CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::vector<byte> >;
  1014. /// \brief Incorporates input into RNG as additional entropy
  1015. /// \since Crypto++ 4.0
  1016. class RandomNumberSink : public Bufferless<Sink>
  1017. {
  1018. public:
  1019. virtual ~RandomNumberSink() {}
  1020. /// \brief Construct a RandomNumberSink
  1021. RandomNumberSink()
  1022. : m_rng(NULLPTR) {}
  1023. /// \brief Construct a RandomNumberSink
  1024. /// \param rng a RandomNumberGenerator derived class
  1025. RandomNumberSink(RandomNumberGenerator &rng)
  1026. : m_rng(&rng) {}
  1027. void IsolatedInitialize(const NameValuePairs &parameters);
  1028. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
  1029. private:
  1030. RandomNumberGenerator *m_rng;
  1031. };
  1032. /// \brief Copy input to a memory buffer
  1033. /// \details ArraySink wraps a fixed size buffer. The buffer is full once Put returns non-0.
  1034. /// When used in a pipeline, ArraySink silently discards input if the buffer is full.
  1035. /// AvailableSize() can be used to determine how much space remains in the buffer.
  1036. /// TotalPutLength() can be used to determine how many bytes were processed.
  1037. /// \sa StringSink, ArrayXorSink
  1038. /// \since Crypto++ 4.0
  1039. class CRYPTOPP_DLL ArraySink : public Bufferless<Sink>
  1040. {
  1041. public:
  1042. virtual ~ArraySink() {}
  1043. /// \brief Construct an ArraySink
  1044. /// \param parameters a set of NameValuePairs to initialize this object
  1045. /// \details Name::OutputBuffer() is a mandatory parameter using this constructor.
  1046. ArraySink(const NameValuePairs &parameters = g_nullNameValuePairs)
  1047. : m_buf(NULLPTR), m_size(0), m_total(0) {IsolatedInitialize(parameters);}
  1048. /// \brief Construct an ArraySink
  1049. /// \param buf pointer to a memory buffer
  1050. /// \param size length of the memory buffer
  1051. ArraySink(byte *buf, size_t size)
  1052. : m_buf(buf), m_size(size), m_total(0) {}
  1053. /// \brief Provides the size remaining in the Sink
  1054. /// \return size remaining in the Sink, in bytes
  1055. size_t AvailableSize() {return SaturatingSubtract(m_size, m_total);}
  1056. /// \brief Provides the number of bytes written to the Sink
  1057. /// \return number of bytes written to the Sink, in bytes
  1058. lword TotalPutLength() {return m_total;}
  1059. void IsolatedInitialize(const NameValuePairs &parameters);
  1060. byte * CreatePutSpace(size_t &size);
  1061. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
  1062. protected:
  1063. byte *m_buf;
  1064. size_t m_size;
  1065. lword m_total;
  1066. };
  1067. /// \brief Xor input to a memory buffer
  1068. /// \details ArrayXorSink wraps a fixed size buffer. The buffer is full once Put returns non-0.
  1069. /// When used in a pipeline, ArrayXorSink silently discards input if the buffer is full.
  1070. /// AvailableSize() can be used to determine how much space remains in the buffer.
  1071. /// TotalPutLength() can be used to determine how many bytes were processed.
  1072. /// \sa StringSink, ArraySink
  1073. /// \since Crypto++ 4.0
  1074. class CRYPTOPP_DLL ArrayXorSink : public ArraySink
  1075. {
  1076. public:
  1077. virtual ~ArrayXorSink() {}
  1078. /// \brief Construct an ArrayXorSink
  1079. /// \param buf pointer to a memory buffer
  1080. /// \param size length of the memory buffer
  1081. ArrayXorSink(byte *buf, size_t size)
  1082. : ArraySink(buf, size) {}
  1083. size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking);
  1084. byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);}
  1085. };
  1086. /// \brief String-based implementation of Store interface
  1087. /// \since Crypto++ 4.0
  1088. class StringStore : public Store
  1089. {
  1090. public:
  1091. /// \brief Construct a StringStore
  1092. /// \param string pointer to a C-String
  1093. StringStore(const char *string = NULLPTR)
  1094. {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
  1095. /// \brief Construct a StringStore
  1096. /// \param string pointer to a memory buffer
  1097. /// \param length size of the memory buffer
  1098. StringStore(const byte *string, size_t length)
  1099. {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
  1100. /// \brief Construct a StringStore
  1101. /// \tparam T std::basic_string<char> type
  1102. /// \param string reference to a std::basic_string<char> type
  1103. template <class T> StringStore(const T &string)
  1104. {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
  1105. CRYPTOPP_DLL size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
  1106. CRYPTOPP_DLL size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
  1107. private:
  1108. CRYPTOPP_DLL void StoreInitialize(const NameValuePairs &parameters);
  1109. const byte *m_store;
  1110. size_t m_length, m_count;
  1111. };
  1112. /// \brief RNG-based implementation of Source interface
  1113. /// \since Crypto++ 4.0
  1114. class CRYPTOPP_DLL RandomNumberStore : public Store
  1115. {
  1116. public:
  1117. virtual ~RandomNumberStore() {}
  1118. RandomNumberStore()
  1119. : m_rng(NULLPTR), m_length(0), m_count(0) {}
  1120. RandomNumberStore(RandomNumberGenerator &rng, lword length)
  1121. : m_rng(&rng), m_length(length), m_count(0) {}
  1122. bool AnyRetrievable() const {return MaxRetrievable() != 0;}
  1123. lword MaxRetrievable() const {return m_length-m_count;}
  1124. size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
  1125. size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
  1126. {
  1127. CRYPTOPP_UNUSED(target); CRYPTOPP_UNUSED(begin); CRYPTOPP_UNUSED(end); CRYPTOPP_UNUSED(channel); CRYPTOPP_UNUSED(blocking);
  1128. throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store");
  1129. }
  1130. private:
  1131. void StoreInitialize(const NameValuePairs &parameters);
  1132. RandomNumberGenerator *m_rng;
  1133. lword m_length, m_count;
  1134. };
  1135. /// \brief Empty store
  1136. /// \since Crypto++ 5.0
  1137. class CRYPTOPP_DLL NullStore : public Store
  1138. {
  1139. public:
  1140. NullStore(lword size = ULONG_MAX) : m_size(size) {}
  1141. void StoreInitialize(const NameValuePairs &parameters)
  1142. {CRYPTOPP_UNUSED(parameters);}
  1143. lword MaxRetrievable() const {return m_size;}
  1144. size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
  1145. size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
  1146. private:
  1147. lword m_size;
  1148. };
  1149. /// \brief Implementation of BufferedTransformation's attachment interface
  1150. /// \details Source is a cornerstone of the Pipeline trinitiy. Data flows from
  1151. /// Sources, through Filters, and then terminates in Sinks. The difference
  1152. /// between a Source and Filter is a Source \a pumps data, while a Filter does
  1153. /// not. The difference between a Filter and a Sink is a Filter allows an
  1154. /// attached transformation, while a Sink does not.
  1155. /// \details See the discussion of BufferedTransformation in cryptlib.h for
  1156. /// more details.
  1157. /// \sa Store and SourceTemplate
  1158. /// \since Crypto++ 1.0
  1159. class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting<Filter>
  1160. {
  1161. public:
  1162. virtual ~Source() {}
  1163. /// \brief Construct a Source
  1164. /// \param attachment an optional attached transformation
  1165. Source(BufferedTransformation *attachment = NULLPTR)
  1166. {Source::Detach(attachment);}
  1167. /// \name PIPELINE
  1168. //@{
  1169. /// \brief Pump data to attached transformation
  1170. /// \param pumpMax the maximum number of bytes to pump
  1171. /// \return the number of bytes that remain to be processed (i.e., bytes not processed).
  1172. /// 0 indicates all bytes were processed.
  1173. /// \details Internally, Pump() calls Pump2().
  1174. /// \note pumpMax is a <tt>lword</tt>, which is a 64-bit value that typically uses
  1175. /// <tt>LWORD_MAX</tt>. The default argument is <tt>SIZE_MAX</tt>, and it can be
  1176. /// 32-bits or 64-bits.
  1177. /// \sa Pump2, PumpAll, AnyRetrievable, MaxRetrievable
  1178. lword Pump(lword pumpMax=SIZE_MAX)
  1179. {Pump2(pumpMax); return pumpMax;}
  1180. /// \brief Pump messages to attached transformation
  1181. /// \param count the maximum number of messages to pump
  1182. /// \return TODO
  1183. /// \details Internally, PumpMessages() calls PumpMessages2().
  1184. unsigned int PumpMessages(unsigned int count=UINT_MAX)
  1185. {PumpMessages2(count); return count;}
  1186. /// \brief Pump all data to attached transformation
  1187. /// \details Pumps all data to the attached transformation and signal the end of the current
  1188. /// message. To avoid the MessageEnd() signal call \ref Pump "Pump(LWORD_MAX)" or \ref Pump2
  1189. /// "Pump2(LWORD_MAX, bool)".
  1190. /// \details Internally, PumpAll() calls PumpAll2(), which calls PumpMessages().
  1191. /// \sa Pump, Pump2, AnyRetrievable, MaxRetrievable
  1192. void PumpAll()
  1193. {PumpAll2();}
  1194. /// \brief Pump data to attached transformation
  1195. /// \param byteCount the maximum number of bytes to pump
  1196. /// \param blocking specifies whether the object should block when processing input
  1197. /// \return the number of bytes that remain to be processed (i.e., bytes not processed).
  1198. /// 0 indicates all bytes were processed.
  1199. /// \details byteCount is an \a IN and \a OUT parameter. When the call is made, byteCount is the
  1200. /// requested size of the pump. When the call returns, byteCount is the number of bytes that
  1201. /// were pumped.
  1202. /// \sa Pump, PumpAll, AnyRetrievable, MaxRetrievable
  1203. virtual size_t Pump2(lword &byteCount, bool blocking=true) =0;
  1204. /// \brief Pump messages to attached transformation
  1205. /// \param messageCount the maximum number of messages to pump
  1206. /// \param blocking specifies whether the object should block when processing input
  1207. /// \details messageCount is an IN and OUT parameter.
  1208. virtual size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) =0;
  1209. /// \brief Pump all data to attached transformation
  1210. /// \param blocking specifies whether the object should block when processing input
  1211. /// \return the number of bytes that remain to be processed (i.e., bytes not processed).
  1212. /// 0 indicates all bytes were processed.
  1213. /// \sa Pump, Pump2, AnyRetrievable, MaxRetrievable
  1214. virtual size_t PumpAll2(bool blocking=true);
  1215. /// \brief Determines if the Source is exhausted
  1216. /// \return true if the source has been exhausted
  1217. virtual bool SourceExhausted() const =0;
  1218. //@}
  1219. protected:
  1220. void SourceInitialize(bool pumpAll, const NameValuePairs &parameters)
  1221. {
  1222. IsolatedInitialize(parameters);
  1223. if (pumpAll)
  1224. PumpAll();
  1225. }
  1226. };
  1227. /// \brief Transform a Store into a Source
  1228. /// \tparam T the class or type
  1229. /// \since Crypto++ 5.0
  1230. template <class T>
  1231. class SourceTemplate : public Source
  1232. {
  1233. public:
  1234. virtual ~SourceTemplate() {}
  1235. /// \brief Construct a SourceTemplate
  1236. /// \param attachment an attached transformation
  1237. SourceTemplate(BufferedTransformation *attachment)
  1238. : Source(attachment) {}
  1239. void IsolatedInitialize(const NameValuePairs &parameters)
  1240. {m_store.IsolatedInitialize(parameters);}
  1241. size_t Pump2(lword &byteCount, bool blocking=true)
  1242. {return m_store.TransferTo2(*AttachedTransformation(), byteCount, DEFAULT_CHANNEL, blocking);}
  1243. size_t PumpMessages2(unsigned int &messageCount, bool blocking=true)
  1244. {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, DEFAULT_CHANNEL, blocking);}
  1245. size_t PumpAll2(bool blocking=true)
  1246. {return m_store.TransferAllTo2(*AttachedTransformation(), DEFAULT_CHANNEL, blocking);}
  1247. bool SourceExhausted() const
  1248. {return !m_store.AnyRetrievable() && !m_store.AnyMessages();}
  1249. void SetAutoSignalPropagation(int propagation)
  1250. {m_store.SetAutoSignalPropagation(propagation);}
  1251. int GetAutoSignalPropagation() const
  1252. {return m_store.GetAutoSignalPropagation();}
  1253. protected:
  1254. T m_store;
  1255. };
  1256. /// \brief String-based implementation of the Source interface
  1257. /// \since Crypto++ 4.0
  1258. class CRYPTOPP_DLL StringSource : public SourceTemplate<StringStore>
  1259. {
  1260. public:
  1261. /// \brief Construct a StringSource
  1262. /// \param attachment an optional attached transformation
  1263. StringSource(BufferedTransformation *attachment = NULLPTR)
  1264. : SourceTemplate<StringStore>(attachment) {}
  1265. /// \brief Construct a StringSource
  1266. /// \param string C-String
  1267. /// \param pumpAll flag indicating if source data should be pumped to its attached transformation
  1268. /// \param attachment an optional attached transformation
  1269. StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULLPTR)
  1270. : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
  1271. /// \brief Construct a StringSource
  1272. /// \param string binary byte array
  1273. /// \param length size of the byte array
  1274. /// \param pumpAll flag indicating if source data should be pumped to its attached transformation
  1275. /// \param attachment an optional attached transformation
  1276. StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULLPTR)
  1277. : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));}
  1278. /// \brief Construct a StringSource
  1279. /// \param string std::string
  1280. /// \param pumpAll flag indicating if source data should be pumped to its attached transformation
  1281. /// \param attachment an optional attached transformation
  1282. StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULLPTR)
  1283. : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));}
  1284. };
  1285. /// \brief Pointer-based implementation of the Source interface
  1286. /// \details ArraySource is a typedef for StringSource. Use the third constructor for an array source.
  1287. /// The third constructor takes a pointer and length.
  1288. /// \since Crypto++ 5.6.0
  1289. DOCUMENTED_TYPEDEF(StringSource, ArraySource);
  1290. /// \brief std::vector-based implementation of the Source interface
  1291. /// \since Crypto++ 8.0
  1292. class CRYPTOPP_DLL VectorSource : public SourceTemplate<StringStore>
  1293. {
  1294. public:
  1295. /// \brief Construct a VectorSource
  1296. /// \param attachment an optional attached transformation
  1297. VectorSource(BufferedTransformation *attachment = NULLPTR)
  1298. : SourceTemplate<StringStore>(attachment) {}
  1299. /// \brief Construct a VectorSource
  1300. /// \param vec vector of bytes
  1301. /// \param pumpAll flag indicating if source data should be pumped to its attached transformation
  1302. /// \param attachment an optional attached transformation
  1303. VectorSource(const std::vector<byte> &vec, bool pumpAll, BufferedTransformation *attachment = NULLPTR)
  1304. : SourceTemplate<StringStore>(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(vec)));}
  1305. };
  1306. /// \brief RNG-based implementation of Source interface
  1307. /// \since Crypto++ 4.0
  1308. class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate<RandomNumberStore>
  1309. {
  1310. public:
  1311. RandomNumberSource(RandomNumberGenerator &rng, int length, bool pumpAll, BufferedTransformation *attachment = NULLPTR)
  1312. : SourceTemplate<RandomNumberStore>(attachment)
  1313. {SourceInitialize(pumpAll, MakeParameters("RandomNumberGeneratorPointer", &rng)("RandomNumberStoreSize", length));}
  1314. };
  1315. NAMESPACE_END
  1316. #if CRYPTOPP_MSC_VERSION
  1317. # pragma warning(pop)
  1318. #endif
  1319. #endif