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