Botan  2.1.0
Crypto and TLS for C++11
pipe.h
Go to the documentation of this file.
1 /*
2 * Pipe
3 * (C) 1999-2007 Jack Lloyd
4 * 2012 Markus Wanner
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #ifndef BOTAN_PIPE_H__
10 #define BOTAN_PIPE_H__
11 
12 #include <botan/data_src.h>
13 #include <botan/filter.h>
14 #include <botan/exceptn.h>
15 #include <initializer_list>
16 #include <iosfwd>
17 
18 namespace Botan {
19 
20 /**
21 * This class represents pipe objects.
22 * A set of filters can be placed into a pipe, and information flows
23 * through the pipe until it reaches the end, where the output is
24 * collected for retrieval. If you're familiar with the Unix shell
25 * environment, this design will sound quite familiar.
26 */
27 class BOTAN_DLL Pipe final : public DataSource
28  {
29  public:
30  /**
31  * An opaque type that identifies a message in this Pipe
32  */
33  typedef size_t message_id;
34 
35  /**
36  * Exception if you use an invalid message as an argument to
37  * read, remaining, etc
38  */
39  struct BOTAN_DLL Invalid_Message_Number : public Invalid_Argument
40  {
41  /**
42  * @param where the error occurred
43  * @param msg the invalid message id that was used
44  */
45  Invalid_Message_Number(const std::string& where, message_id msg) :
46  Invalid_Argument("Pipe::" + where + ": Invalid message number " +
47  std::to_string(msg))
48  {}
49  };
50 
51  /**
52  * A meta-id for whatever the last message is
53  */
54  static const message_id LAST_MESSAGE;
55 
56  /**
57  * A meta-id for the default message (set with set_default_msg)
58  */
59  static const message_id DEFAULT_MESSAGE;
60 
61  /**
62  * Write input to the pipe, i.e. to its first filter.
63  * @param in the byte array to write
64  * @param length the length of the byte array in
65  */
66  void write(const uint8_t in[], size_t length);
67 
68  /**
69  * Write input to the pipe, i.e. to its first filter.
70  * @param in the secure_vector containing the data to write
71  */
72  void write(const secure_vector<uint8_t>& in)
73  { write(in.data(), in.size()); }
74 
75  /**
76  * Write input to the pipe, i.e. to its first filter.
77  * @param in the std::vector containing the data to write
78  */
79  void write(const std::vector<uint8_t>& in)
80  { write(in.data(), in.size()); }
81 
82  /**
83  * Write input to the pipe, i.e. to its first filter.
84  * @param in the string containing the data to write
85  */
86  void write(const std::string& in);
87 
88  /**
89  * Write input to the pipe, i.e. to its first filter.
90  * @param in the DataSource to read the data from
91  */
92  void write(DataSource& in);
93 
94  /**
95  * Write input to the pipe, i.e. to its first filter.
96  * @param in a single byte to be written
97  */
98  void write(uint8_t in);
99 
100  /**
101  * Perform start_msg(), write() and end_msg() sequentially.
102  * @param in the byte array containing the data to write
103  * @param length the length of the byte array to write
104  */
105  void process_msg(const uint8_t in[], size_t length);
106 
107  /**
108  * Perform start_msg(), write() and end_msg() sequentially.
109  * @param in the secure_vector containing the data to write
110  */
111  void process_msg(const secure_vector<uint8_t>& in);
112 
113  /**
114  * Perform start_msg(), write() and end_msg() sequentially.
115  * @param in the secure_vector containing the data to write
116  */
117  void process_msg(const std::vector<uint8_t>& in);
118 
119  /**
120  * Perform start_msg(), write() and end_msg() sequentially.
121  * @param in the string containing the data to write
122  */
123  void process_msg(const std::string& in);
124 
125  /**
126  * Perform start_msg(), write() and end_msg() sequentially.
127  * @param in the DataSource providing the data to write
128  */
129  void process_msg(DataSource& in);
130 
131  /**
132  * Find out how many bytes are ready to read.
133  * @param msg the number identifying the message
134  * for which the information is desired
135  * @return number of bytes that can still be read
136  */
137  size_t remaining(message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT;
138 
139  /**
140  * Read the default message from the pipe. Moves the internal
141  * offset so that every call to read will return a new portion of
142  * the message.
143  *
144  * @param output the byte array to write the read bytes to
145  * @param length the length of the byte array output
146  * @return number of bytes actually read into output
147  */
148  size_t read(uint8_t output[], size_t length) override BOTAN_WARN_UNUSED_RESULT;
149 
150  /**
151  * Read a specified message from the pipe. Moves the internal
152  * offset so that every call to read will return a new portion of
153  * the message.
154  * @param output the byte array to write the read bytes to
155  * @param length the length of the byte array output
156  * @param msg the number identifying the message to read from
157  * @return number of bytes actually read into output
158  */
159  size_t read(uint8_t output[], size_t length, message_id msg) BOTAN_WARN_UNUSED_RESULT;
160 
161  /**
162  * Read a single byte from the pipe. Moves the internal offset so
163  * that every call to read will return a new portion of the
164  * message.
165  *
166  * @param output the byte to write the result to
167  * @param msg the message to read from
168  * @return number of bytes actually read into output
169  */
170  size_t read(uint8_t& output, message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT;
171 
172  /**
173  * Read the full contents of the pipe.
174  * @param msg the number identifying the message to read from
175  * @return secure_vector holding the contents of the pipe
176  */
177  secure_vector<uint8_t> read_all(message_id msg = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT;
178 
179  /**
180  * Read the full contents of the pipe.
181  * @param msg the number identifying the message to read from
182  * @return string holding the contents of the pipe
183  */
184  std::string read_all_as_string(message_id = DEFAULT_MESSAGE) BOTAN_WARN_UNUSED_RESULT;
185 
186  /**
187  * Read from the default message but do not modify the internal
188  * offset. Consecutive calls to peek() will return portions of
189  * the message starting at the same position.
190  * @param output the byte array to write the peeked message part to
191  * @param length the length of the byte array output
192  * @param offset the offset from the current position in message
193  * @return number of bytes actually peeked and written into output
194  */
195  size_t peek(uint8_t output[], size_t length, size_t offset) const override BOTAN_WARN_UNUSED_RESULT;
196 
197  /** Read from the specified message but do not modify the
198  * internal offset. Consecutive calls to peek() will return
199  * portions of the message starting at the same position.
200  * @param output the byte array to write the peeked message part to
201  * @param length the length of the byte array output
202  * @param offset the offset from the current position in message
203  * @param msg the number identifying the message to peek from
204  * @return number of bytes actually peeked and written into output
205  */
206  size_t peek(uint8_t output[], size_t length,
207  size_t offset, message_id msg) const BOTAN_WARN_UNUSED_RESULT;
208 
209  /** Read a single byte from the specified message but do not
210  * modify the internal offset. Consecutive calls to peek() will
211  * return portions of the message starting at the same position.
212  * @param output the byte to write the peeked message byte to
213  * @param offset the offset from the current position in message
214  * @param msg the number identifying the message to peek from
215  * @return number of bytes actually peeked and written into output
216  */
217  size_t peek(uint8_t& output, size_t offset,
218  message_id msg = DEFAULT_MESSAGE) const BOTAN_WARN_UNUSED_RESULT;
219 
220  /**
221  * @return the number of bytes read from the default message.
222  */
223  size_t get_bytes_read() const override;
224 
225  /**
226  * @return the number of bytes read from the specified message.
227  */
228  size_t get_bytes_read(message_id msg) const;
229 
230  bool check_available(size_t n) override;
231  bool check_available_msg(size_t n, message_id msg);
232 
233  /**
234  * @return currently set default message
235  */
236  size_t default_msg() const { return m_default_read; }
237 
238  /**
239  * Set the default message
240  * @param msg the number identifying the message which is going to
241  * be the new default message
242  */
243  void set_default_msg(message_id msg);
244 
245  /**
246  * Get the number of messages the are in this pipe.
247  * @return number of messages the are in this pipe
248  */
249  message_id message_count() const;
250 
251  /**
252  * Test whether this pipe has any data that can be read from.
253  * @return true if there is more data to read, false otherwise
254  */
255  bool end_of_data() const override;
256 
257  /**
258  * Start a new message in the pipe. A potential other message in this pipe
259  * must be closed with end_msg() before this function may be called.
260  */
261  void start_msg();
262 
263  /**
264  * End the current message.
265  */
266  void end_msg();
267 
268  /**
269  * Insert a new filter at the front of the pipe
270  * @param filt the new filter to insert
271  */
272  void prepend(Filter* filt);
273 
274  /**
275  * Insert a new filter at the back of the pipe
276  * @param filt the new filter to insert
277  */
278  void append(Filter* filt);
279 
280  /**
281  * Remove the first filter at the front of the pipe.
282  */
283  void pop();
284 
285  /**
286  * Reset this pipe to an empty pipe.
287  */
288  void reset();
289 
290  /**
291  * Construct a Pipe of up to four filters. The filters are set up
292  * in the same order as the arguments.
293  */
294  Pipe(Filter* = nullptr, Filter* = nullptr,
295  Filter* = nullptr, Filter* = nullptr);
296 
297  /**
298  * Construct a Pipe from a list of filters
299  * @param filters the set of filters to use
300  */
301  explicit Pipe(std::initializer_list<Filter*> filters);
302 
303  Pipe(const Pipe&) = delete;
304  Pipe& operator=(const Pipe&) = delete;
305 
306  ~Pipe();
307  private:
308  void init();
309  void destruct(Filter*);
310  void find_endpoints(Filter*);
311  void clear_endpoints(Filter*);
312 
313  message_id get_message_no(const std::string&, message_id) const;
314 
315  Filter* m_pipe;
316  class Output_Buffers* m_outputs;
317  message_id m_default_read;
318  bool m_inside_msg;
319  };
320 
321 /**
322 * Stream output operator; dumps the results from pipe's default
323 * message to the output stream.
324 * @param out an output stream
325 * @param pipe the pipe
326 */
327 BOTAN_DLL std::ostream& operator<<(std::ostream& out, Pipe& pipe);
328 
329 /**
330 * Stream input operator; dumps the remaining bytes of input
331 * to the (assumed open) pipe message.
332 * @param in the input stream
333 * @param pipe the pipe
334 */
335 BOTAN_DLL std::istream& operator>>(std::istream& in, Pipe& pipe);
336 
337 }
338 
339 #if defined(BOTAN_HAS_PIPE_UNIXFD_IO)
340  #include <botan/fd_unix.h>
341 #endif
342 
343 #endif
std::istream & operator>>(std::istream &in, X509_DN &dn)
Definition: x509_dn.cpp:325
Invalid_Message_Number(const std::string &where, message_id msg)
Definition: pipe.h:45
size_t message_id
Definition: pipe.h:33
std::ostream & operator<<(std::ostream &out, const X509_DN &dn)
Definition: x509_dn.cpp:299
Definition: bigint.h:619
#define BOTAN_WARN_UNUSED_RESULT
Definition: compiler.h:57
static const message_id DEFAULT_MESSAGE
Definition: pipe.h:59
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
static const message_id LAST_MESSAGE
Definition: pipe.h:54
Definition: alg_id.cpp:13
void write(const secure_vector< uint8_t > &in)
Definition: pipe.h:72
void write(const std::vector< uint8_t > &in)
Definition: pipe.h:79
std::string to_string(const secure_vector< uint8_t > &bytes)
Definition: stl_util.h:25