Botan 3.13.0
Crypto and TLS for C&
filters.h
Go to the documentation of this file.
1/*
2* Common Filters
3* (C) 1999-2007,2015 Jack Lloyd
4* (C) 2013 Joel Low
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_FILTERS_H_
10#define BOTAN_FILTERS_H_
11
12#include <botan/cipher_mode.h>
13#include <botan/data_snk.h>
14#include <botan/pipe.h>
15#include <botan/secmem.h>
16#include <botan/symkey.h>
17
18#if defined(BOTAN_TARGET_OS_HAS_THREADS)
19 #include <thread>
20#endif
21
22#if defined(BOTAN_HAS_STREAM_CIPHER)
23 #include <botan/stream_cipher.h>
24#endif
25
26#if defined(BOTAN_HAS_HASH)
27 #include <botan/hash.h>
28#endif
29
30#if defined(BOTAN_HAS_MAC)
31 #include <botan/mac.h>
32#endif
33
34namespace Botan {
35
36/**
37* Filter mixin that breaks input into blocks, useful for
38* cipher modes
39*/
40class BOTAN_PUBLIC_API(2, 0) Buffered_Filter /* NOLINT(*-special-member-functions) */ {
41 public:
42 /**
43 * Write bytes into the buffered filter, which will them emit them
44 * in calls to buffered_block in the subclass
45 * @param in the input bytes
46 * @param length of in in bytes
47 */
48 void write(const uint8_t in[], size_t length);
49
50 /**
51 * Write bytes into the buffered filter, which will them emit them
52 * in calls to buffered_block in the subclass
53 * @param in the input bytes
54 * @param length of in in bytes
55 */
56 template <typename Alloc>
57 void write(const std::vector<uint8_t, Alloc>& in, size_t length) {
58 write(in.data(), length);
59 }
60
61 /**
62 * Finish a message, emitting to buffered_block and buffered_final
63 * Will throw an exception if less than final_minimum bytes were
64 * written into the filter.
65 */
66 void end_msg();
67
68 /**
69 * Initialize a Buffered_Filter
70 * @param block_size the function buffered_block will be called
71 * with inputs which are a multiple of this size
72 * @param final_minimum the function buffered_final will be called
73 * with at least this many bytes.
74 */
75 Buffered_Filter(size_t block_size, size_t final_minimum);
76
77 virtual ~Buffered_Filter() = default;
78
79 protected:
80 /**
81 * The block processor, implemented by subclasses
82 * @param input some input bytes
83 * @param length the size of input, guaranteed to be a multiple
84 * of block_size
85 */
86 virtual void buffered_block(const uint8_t input[], size_t length) = 0;
87
88 /**
89 * The final block, implemented by subclasses
90 * @param input some input bytes
91 * @param length the size of input, guaranteed to be at least
92 * final_minimum bytes
93 */
94 virtual void buffered_final(const uint8_t input[], size_t length) = 0;
95
96 /**
97 * Return the block size of buffered inputs
98 * @return block size of inputs
99 */
100 size_t buffered_block_size() const { return m_main_block_mod; }
101
102 /**
103 * Return the current position in the buffer
104 * @return current position in the buffer
105 */
106 size_t current_position() const { return m_buffer_pos; }
107
108 /**
109 * Reset the buffer position
110 */
111 void buffer_reset() { m_buffer_pos = 0; }
112
113 private:
114 size_t m_main_block_mod, m_final_minimum;
115
116 secure_vector<uint8_t> m_buffer;
117 size_t m_buffer_pos;
118};
119
120/**
121* This class represents keyed filters, i.e. filters that have to be
122* fed with a key in order to function.
123*/
125 public:
126 /**
127 * Set the key of this filter
128 * @param key the key to use
129 */
130 virtual void set_key(const SymmetricKey& key) = 0;
131
132 /**
133 * Set the initialization vector of this filter. Note: you should
134 * call set_iv() only after you have called set_key()
135 * @param iv the initialization vector to use
136 */
137 virtual void set_iv(const InitializationVector& iv) {
138 if(!iv.empty()) {
139 throw Invalid_IV_Length(name(), iv.length());
140 }
141 }
142
143 /**
144 * Check whether a key length is valid for this filter
145 * @param length the key length to be checked for validity
146 * @return true if the key length is valid, false otherwise
147 */
148 bool valid_keylength(size_t length) const { return key_spec().valid_keylength(length); }
149
150 /**
151 * Return object describing limitations on key size
152 */
154
155 /**
156 * Check whether an IV length is valid for this filter
157 * @param length the IV length to be checked for validity
158 * @return true if the IV length is valid, false otherwise
159 */
160 virtual bool valid_iv_length(size_t length) const { return (length == 0); }
161};
162
163/**
164* Filter interface for cipher modes
165*/
167 private Buffered_Filter {
168 public:
169 /**
170 * Construct a filter wrapping the given cipher mode
171 * @param t the cipher mode to use
172 */
173 explicit Cipher_Mode_Filter(Cipher_Mode* t);
174
175 /**
176 * Construct a filter wrapping the given cipher mode
177 * @param t the cipher mode to use
178 */
179 explicit Cipher_Mode_Filter(std::unique_ptr<Cipher_Mode> t) : Cipher_Mode_Filter(t.release()) {}
180
181 /**
182 * Set the initialization vector for this filter
183 * @param iv the initialization vector to set
184 */
185 void set_iv(const InitializationVector& iv) override;
186
187 /**
188 * Set the key of this filter
189 * @param key the key to set
190 */
191 void set_key(const SymmetricKey& key) override;
192
193 /**
194 * Return the key lengths supported by this filter
195 * @return the key length specification
196 */
197 Key_Length_Specification key_spec() const override;
198
199 /**
200 * Check whether an IV length is valid for this filter
201 * @param length the IV length to be checked for validity
202 * @return true if the IV length is valid
203 */
204 bool valid_iv_length(size_t length) const override;
205
206 /**
207 * Return a descriptive name for this filter
208 * @return the name of the underlying cipher mode
209 */
210 std::string name() const override;
211
212 private:
213 void write(const uint8_t input[], size_t input_length) override;
214 void start_msg() override;
215 void end_msg() override;
216
217 void buffered_block(const uint8_t input[], size_t input_length) override;
218 void buffered_final(const uint8_t input[], size_t input_length) override;
219
220 std::unique_ptr<Cipher_Mode> m_mode;
221 std::vector<uint8_t> m_nonce;
222 secure_vector<uint8_t> m_buffer;
223};
224
225/*
226* Get a cipher object
227*/
228
229/**
230* Factory method for general symmetric cipher filters. No key will be
231* set in the filter.
232*
233* @param algo_spec the name of the desired cipher
234* @param direction determines whether the filter will be an encrypting or
235* decrypting filter
236* @return pointer to the encryption or decryption filter
237*/
238inline Keyed_Filter* get_cipher(std::string_view algo_spec, Cipher_Dir direction) {
239 auto c = Cipher_Mode::create_or_throw(algo_spec, direction);
240 // NOLINTNEXTLINE(*-owning-memory)
241 return new Cipher_Mode_Filter(c.release());
242}
243
244/**
245* Factory method for general symmetric cipher filters.
246* @param algo_spec the name of the desired cipher
247* @param key the key to be used for encryption/decryption performed by
248* the filter
249* @param direction determines whether the filter will be an encrypting
250* or decrypting filter
251* @return pointer to the encryption or decryption filter
252*/
253inline Keyed_Filter* get_cipher(std::string_view algo_spec, const SymmetricKey& key, Cipher_Dir direction) {
254 Keyed_Filter* cipher = get_cipher(algo_spec, direction);
255 cipher->set_key(key);
256 return cipher;
257}
258
259/**
260* Factory method for general symmetric cipher filters.
261* @param algo_spec the name of the desired cipher
262* @param key the key to be used for encryption/decryption performed by
263* the filter
264* @param iv the initialization vector to be used
265* @param direction determines whether the filter will be an encrypting
266* or decrypting filter
267* @return pointer to newly allocated encryption or decryption filter
268*/
269inline Keyed_Filter* get_cipher(std::string_view algo_spec,
270 const SymmetricKey& key,
271 const InitializationVector& iv,
272 Cipher_Dir direction) {
273 Keyed_Filter* cipher = get_cipher(algo_spec, key, direction);
274 if(!iv.empty()) {
275 cipher->set_iv(iv);
276 }
277 return cipher;
278}
279
280#if defined(BOTAN_HAS_STREAM_CIPHER)
281
282/**
283* Stream Cipher Filter
284*/
285class BOTAN_PUBLIC_API(2, 0) StreamCipher_Filter final : public Keyed_Filter {
286 public:
287 /**
288 * Return a descriptive name for this filter
289 * @return the name of the underlying cipher
290 */
291 std::string name() const override { return m_cipher->name(); }
292
293 /**
294 * Write input data
295 * @param input data
296 * @param input_len length of input in bytes
297 */
298 void write(const uint8_t input[], size_t input_len) override;
299
300 /**
301 * Check whether an IV length is valid for this filter
302 * @param iv_len the IV length to be checked for validity
303 * @return true if the IV length is valid
304 */
305 bool valid_iv_length(size_t iv_len) const override { return m_cipher->valid_iv_length(iv_len); }
306
307 /**
308 * Set the initialization vector for this filter.
309 * @param iv the initialization vector to set
310 */
311 void set_iv(const InitializationVector& iv) override { m_cipher->set_iv(iv.begin(), iv.length()); }
312
313 /**
314 * Set the key of this filter.
315 * @param key the key to set
316 */
317 void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); }
318
319 /**
320 * Return the key lengths supported by this filter
321 * @return the key length specification
322 */
323 Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); }
324
325 /**
326 * Construct a stream cipher filter.
327 * @param cipher a cipher object to use
328 */
329 explicit StreamCipher_Filter(StreamCipher* cipher);
330
331 /**
332 * Construct a stream cipher filter.
333 * @param cipher a cipher object to use
334 * @param key the key to use inside this filter
335 */
336 StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key);
337
338 /**
339 * Construct a stream cipher filter.
340 * @param cipher the name of the desired cipher
341 */
342 explicit StreamCipher_Filter(std::string_view cipher);
343
344 /**
345 * Construct a stream cipher filter.
346 * @param cipher the name of the desired cipher
347 * @param key the key to use inside this filter
348 */
349 StreamCipher_Filter(std::string_view cipher, const SymmetricKey& key);
350
351 private:
352 std::unique_ptr<StreamCipher> m_cipher;
353 secure_vector<uint8_t> m_buffer;
354};
355#endif
356
357#if defined(BOTAN_HAS_HASH)
358
359/**
360* Hash Filter.
361*/
362class BOTAN_PUBLIC_API(2, 0) Hash_Filter final : public Filter {
363 public:
364 /**
365 * Write a portion of a message to this filter
366 * @param input the input as a byte array
367 * @param len the length of the byte array input
368 */
369 void write(const uint8_t input[], size_t len) override { m_hash->update(input, len); }
370
371 /**
372 * Complete the hash and send the digest to the next filter
373 */
374 void end_msg() override;
375
376 /**
377 * Return a descriptive name for this filter
378 * @return the name of the underlying hash
379 */
380 std::string name() const override { return m_hash->name(); }
381
382 /**
383 * Construct a hash filter.
384 * @param hash the hash function to use
385 * @param len the output length of this filter. Leave the default
386 * value 0 if you want to use the full output of the hashfunction
387 * hash. Otherwise, specify a smaller value here so that the
388 * output of the hash algorithm will be cut off.
389 */
390 BOTAN_FUTURE_EXPLICIT Hash_Filter(HashFunction* hash, size_t len = 0) : m_hash(hash), m_out_len(len) {}
391
392 /**
393 * Construct a hash filter.
394 * @param request the name of the hash algorithm to use
395 * @param len the output length of this filter. Leave the default
396 * value 0 if you want to use the full output of the hashfunction
397 * hash. Otherwise, specify a smaller value here so that the
398 * output of the hash algorithm will be cut off.
399 */
400 BOTAN_FUTURE_EXPLICIT Hash_Filter(std::string_view request, size_t len = 0);
401
402 private:
403 std::unique_ptr<HashFunction> m_hash;
404 const size_t m_out_len;
405};
406#endif
407
408#if defined(BOTAN_HAS_MAC)
409
410/**
411* MessageAuthenticationCode Filter.
412*/
413class BOTAN_PUBLIC_API(2, 0) MAC_Filter final : public Keyed_Filter {
414 public:
415 /**
416 * Write a portion of a message to this filter
417 * @param input the input as a byte array
418 * @param len the length of the byte array input
419 */
420 void write(const uint8_t input[], size_t len) override { m_mac->update(input, len); }
421
422 /**
423 * Complete the MAC and send the tag to the next filter
424 */
425 void end_msg() override;
426
427 /**
428 * Return a descriptive name for this filter
429 * @return the name of the underlying MAC
430 */
431 std::string name() const override { return m_mac->name(); }
432
433 /**
434 * Set the key of this filter.
435 * @param key the key to set
436 */
437 void set_key(const SymmetricKey& key) override { m_mac->set_key(key); }
438
439 /**
440 * Return the key lengths supported by this filter
441 * @return the key length specification
442 */
443 Key_Length_Specification key_spec() const override { return m_mac->key_spec(); }
444
445 /**
446 * Construct a MAC filter. The MAC key will be left empty.
447 * @param mac the MAC to use
448 * @param out_len the output length of this filter. Leave the default
449 * value 0 if you want to use the full output of the
450 * MAC. Otherwise, specify a smaller value here so that the
451 * output of the MAC will be cut off.
452 */
453 BOTAN_FUTURE_EXPLICIT MAC_Filter(MessageAuthenticationCode* mac, size_t out_len = 0) :
454 m_mac(mac), m_out_len(out_len) {}
455
456 /**
457 * Construct a MAC filter.
458 * @param mac the MAC to use
459 * @param key the MAC key to use
460 * @param out_len the output length of this filter. Leave the default
461 * value 0 if you want to use the full output of the
462 * MAC. Otherwise, specify a smaller value here so that the
463 * output of the MAC will be cut off.
464 */
465 MAC_Filter(MessageAuthenticationCode* mac, const SymmetricKey& key, size_t out_len = 0) :
466 m_mac(mac), m_out_len(out_len) {
467 m_mac->set_key(key);
468 }
469
470 /**
471 * Construct a MAC filter. The MAC key will be left empty.
472 * @param mac the name of the MAC to use
473 * @param len the output length of this filter. Leave the default
474 * value 0 if you want to use the full output of the
475 * MAC. Otherwise, specify a smaller value here so that the
476 * output of the MAC will be cut off.
477 */
478 BOTAN_FUTURE_EXPLICIT MAC_Filter(std::string_view mac, size_t len = 0);
479
480 /**
481 * Construct a MAC filter.
482 * @param mac the name of the MAC to use
483 * @param key the MAC key to use
484 * @param len the output length of this filter. Leave the default
485 * value 0 if you want to use the full output of the
486 * MAC. Otherwise, specify a smaller value here so that the
487 * output of the MAC will be cut off.
488 */
489 MAC_Filter(std::string_view mac, const SymmetricKey& key, size_t len = 0);
490
491 private:
492 std::unique_ptr<MessageAuthenticationCode> m_mac;
493 const size_t m_out_len;
494};
495#endif
496
497#if defined(BOTAN_HAS_COMPRESSION)
498
501
502/**
503* Filter interface for compression
504*/
505class BOTAN_PUBLIC_API(2, 0) Compression_Filter final : public Filter {
506 public:
507 /**
508 * Begin a new message
509 */
510 void start_msg() override;
511 /**
512 * Compress a portion of a message
513 * @param input the input as a byte array
514 * @param input_length the length of the byte array input
515 */
516 void write(const uint8_t input[], size_t input_length) override;
517 /**
518 * Finish compressing and flush all remaining output
519 */
520 void end_msg() override;
521
522 /**
523 * Flush the compression state so far to the next filter
524 */
525 void flush();
526
527 /**
528 * Return a descriptive name for this filter
529 * @return the name of the underlying compression algorithm
530 */
531 std::string name() const override;
532
533 /**
534 * Construct a compression filter
535 * @param type the compression algorithm to use
536 * @param compression_level the desired level of compression
537 * @param buffer_size the working buffer size
538 */
539 Compression_Filter(std::string_view type, size_t compression_level, size_t buffer_size = 4096);
540
541 ~Compression_Filter() override;
542
543 Compression_Filter(const Compression_Filter& other) = delete;
544 Compression_Filter(Compression_Filter&& other) = delete;
545 Compression_Filter& operator=(const Compression_Filter& other) = delete;
546 Compression_Filter& operator=(Compression_Filter&& other) = delete;
547
548 private:
549 std::unique_ptr<Compression_Algorithm> m_comp;
550 size_t m_buffersize, m_level;
551 secure_vector<uint8_t> m_buffer;
552};
553
554/**
555* Filter interface for decompression
556*/
557class BOTAN_PUBLIC_API(2, 0) Decompression_Filter final : public Filter {
558 public:
559 /**
560 * Begin a new message
561 */
562 void start_msg() override;
563 /**
564 * Decompress a portion of a message
565 * @param input the input as a byte array
566 * @param input_length the length of the byte array input
567 */
568 void write(const uint8_t input[], size_t input_length) override;
569 /**
570 * Finish decompressing and flush all remaining output
571 */
572 void end_msg() override;
573
574 /**
575 * Return a descriptive name for this filter
576 * @return the name of the underlying decompression algorithm
577 */
578 std::string name() const override;
579
580 /**
581 * Construct a decompression filter
582 * @param type the decompression algorithm to use
583 * @param buffer_size the working buffer size
584 */
585 BOTAN_FUTURE_EXPLICIT Decompression_Filter(std::string_view type, size_t buffer_size = 4096);
586
587 ~Decompression_Filter() override;
588
589 Decompression_Filter(const Decompression_Filter& other) = delete;
590 Decompression_Filter(Decompression_Filter&& other) = delete;
591 Decompression_Filter& operator=(const Decompression_Filter& other) = delete;
592 Decompression_Filter& operator=(Decompression_Filter&& other) = delete;
593
594 private:
595 std::unique_ptr<Decompression_Algorithm> m_comp;
596 std::size_t m_buffersize;
597 secure_vector<uint8_t> m_buffer;
598};
599
600#endif
601
602/**
603* This class represents a Base64 encoder.
604*/
605class BOTAN_PUBLIC_API(2, 0) Base64_Encoder final : public Filter {
606 public:
607 /**
608 * Return a descriptive name for this filter
609 * @return "Base64_Encoder"
610 */
611 std::string name() const override { return "Base64_Encoder"; }
612
613 /**
614 * Input a part of a message to the encoder.
615 * @param input the message to input as a byte array
616 * @param length the length of the byte array input
617 */
618 void write(const uint8_t input[], size_t length) override;
619
620 /**
621 * Inform the Encoder that the current message shall be closed.
622 */
623 void end_msg() override;
624
625 /**
626 * Create a base64 encoder.
627 * @param line_breaks whether to use line breaks in the output
628 * @param line_length the length of the lines of the output
629 * @param trailing_newline whether to use a trailing newline
630 */
631 BOTAN_FUTURE_EXPLICIT Base64_Encoder(bool line_breaks = false,
632 size_t line_length = 72,
633 bool trailing_newline = false);
634
635 private:
636 void encode_and_send(const uint8_t input[], size_t length, bool final_inputs = false);
637 void do_output(const uint8_t output[], size_t length);
638
639 const size_t m_line_length;
640 const bool m_trailing_newline;
641 std::vector<uint8_t> m_in, m_out;
642 size_t m_position = 0;
643 size_t m_out_position = 0;
644};
645
646/**
647* This object represents a Base64 decoder.
648*/
649class BOTAN_PUBLIC_API(2, 0) Base64_Decoder final : public Filter {
650 public:
651 /**
652 * Return a descriptive name for this filter
653 * @return "Base64_Decoder"
654 */
655 std::string name() const override { return "Base64_Decoder"; }
656
657 /**
658 * Input a part of a message to the decoder.
659 * @param input the message to input as a byte array
660 * @param length the length of the byte array input
661 */
662 void write(const uint8_t input[], size_t length) override;
663
664 /**
665 * Finish up the current message
666 */
667 void end_msg() override;
668
669 /**
670 * Create a base64 decoder.
671 * @param checking the type of checking that shall be performed by
672 * the decoder
673 */
674 explicit Base64_Decoder(Decoder_Checking checking = NONE);
675
676 private:
677 const Decoder_Checking m_checking;
678 std::vector<uint8_t> m_in;
679 std::vector<uint8_t> m_out;
680 size_t m_position = 0;
681};
682
683/**
684* Converts arbitrary binary data to hex strings, optionally with
685* newlines inserted
686*/
687class BOTAN_PUBLIC_API(2, 0) Hex_Encoder final : public Filter {
688 public:
689 /**
690 * Whether to use uppercase or lowercase letters for the encoded string.
691 */
692 enum Case : uint8_t /* NOLINT(*-use-enum-class) */ { Uppercase, Lowercase };
693
694 /**
695 * Return a descriptive name for this filter
696 * @return "Hex_Encoder"
697 */
698 std::string name() const override { return "Hex_Encoder"; }
699
700 /**
701 * Write a portion of a message to this filter
702 * @param in the input as a byte array
703 * @param length the length of the byte array input
704 */
705 void write(const uint8_t in[], size_t length) override;
706 /**
707 * Complete the encoding and flush any buffered output
708 */
709 void end_msg() override;
710
711 /**
712 * Create a hex encoder.
713 * @param the_case the case to use in the encoded strings.
714 */
715 explicit Hex_Encoder(Case the_case);
716
717 /**
718 * Create a hex encoder.
719 * @param newlines should newlines be used
720 * @param line_length if newlines are used, how long are lines
721 * @param the_case the case to use in the encoded strings
722 */
723 BOTAN_FUTURE_EXPLICIT Hex_Encoder(bool newlines = false, size_t line_length = 72, Case the_case = Uppercase);
724
725 private:
726 void encode_and_send(const uint8_t input[], size_t length);
727
728 const Case m_casing;
729 const size_t m_line_length;
730 std::vector<uint8_t> m_in;
731 std::vector<uint8_t> m_out;
732 size_t m_position = 0;
733 size_t m_counter = 0;
734};
735
736/**
737* Converts hex strings to bytes
738*/
739class BOTAN_PUBLIC_API(2, 0) Hex_Decoder final : public Filter {
740 public:
741 /**
742 * Return a descriptive name for this filter
743 * @return "Hex_Decoder"
744 */
745 std::string name() const override { return "Hex_Decoder"; }
746
747 /**
748 * Write a portion of a message to this filter
749 * @param input the input as a byte array
750 * @param length the length of the byte array input
751 */
752 void write(const uint8_t input[], size_t length) override;
753 /**
754 * Complete the decoding and flush any buffered output
755 */
756 void end_msg() override;
757
758 /**
759 * Construct a Hex Decoder using the specified
760 * character checking.
761 * @param checking the checking to use during decoding.
762 */
763 explicit Hex_Decoder(Decoder_Checking checking = NONE);
764
765 private:
766 const Decoder_Checking m_checking;
767 std::vector<uint8_t> m_in, m_out;
768 size_t m_position = 0;
769};
770
771/**
772* BitBucket is a filter which simply discards all inputs
773*/
774class BOTAN_PUBLIC_API(2, 0) BitBucket final : public Filter {
775 public:
776 /**
777 * Discard the provided input
778 */
779 void write(const uint8_t /*input*/[], size_t /*length*/) override { /* discard */
780 }
781
782 /**
783 * Return a descriptive name for this filter
784 * @return "BitBucket"
785 */
786 std::string name() const override { return "BitBucket"; }
787};
788
789/**
790* This class represents Filter chains. A Filter chain is an ordered
791* concatenation of Filters, the input to a Chain sequentially passes
792* through all the Filters contained in the Chain.
793*/
794
795class BOTAN_PUBLIC_API(2, 0) Chain final : public Fanout_Filter {
796 public:
797 /**
798 * Pass the input through to the filters in this chain
799 * @param input the input as a byte array
800 * @param length the length of the byte array input
801 */
802 void write(const uint8_t input[], size_t length) override { send(input, length); }
803
804 /**
805 * Return a descriptive name for this filter
806 * @return "Chain"
807 */
808 std::string name() const override { return "Chain"; }
809
810 /**
811 * Construct a chain of up to four filters. The filters are set
812 * up in the same order as the arguments.
813 */
814 BOTAN_FUTURE_EXPLICIT Chain(Filter* f1 = nullptr,
815 Filter* f2 = nullptr,
816 Filter* f3 = nullptr,
817 Filter* f4 = nullptr);
818
819 /**
820 * Construct a chain from range of filters
821 * @param filter_arr the list of filters
822 * @param length how many filters
823 */
824 Chain(Filter* filter_arr[], size_t length);
825};
826
827/**
828* This class represents a fork filter, whose purpose is to fork the
829* flow of data. It causes an input message to result in n messages at
830* the end of the filter, where n is the number of forks.
831*/
832class BOTAN_PUBLIC_API(2, 0) Fork : public Fanout_Filter {
833 public:
834 /**
835 * Pass the input through to every fork
836 * @param input the input as a byte array
837 * @param length the length of the byte array input
838 */
839 void write(const uint8_t input[], size_t length) override { send(input, length); }
840
841 /**
842 * Select which fork subsequent output is sent to
843 * @param n the index of the fork to select
844 */
845 // NOLINTNEXTLINE(bugprone-derived-method-shadowing-base-method)
846 void set_port(size_t n) { Fanout_Filter::set_port(n); }
847
848 /**
849 * Return a descriptive name for this filter
850 * @return "Fork"
851 */
852 std::string name() const override { return "Fork"; }
853
854 /**
855 * Construct a Fork filter with up to four forks.
856 */
857 Fork(Filter* f1, Filter* f2, Filter* f3 = nullptr, Filter* f4 = nullptr);
858
859 /**
860 * Construct a Fork from range of filters
861 * @param filter_arr the list of filters
862 * @param length how many filters
863 */
864 Fork(Filter* filter_arr[], size_t length);
865};
866
867#if defined(BOTAN_HAS_THREAD_UTILS)
868
869/**
870* This class is a threaded version of the Fork filter. While this uses
871* threads, the class itself is NOT thread-safe. This is meant as a drop-
872* in replacement for Fork where performance gains are possible.
873*
874* This is deprecated as supporting it requires quite a bit of extra complexity
875* and realistically if performance is a concern, avoiding this Pipe/Filters
876* interface entirely is highly recommended.
877*
878* TODO(Botan4) remove this and all associated helpers (like Barrier and Semaphore)
879*/
880class BOTAN_PUBLIC_API(2, 0) Threaded_Fork final : public Fork {
881 public:
882 /**
883 * Return a descriptive name for this filter
884 * @return "Threaded_Fork"
885 */
886 std::string name() const override;
887
888 /**
889 * Construct a Threaded_Fork filter with up to four forks.
890 */
891 BOTAN_DEPRECATED("Deprecated, use plain Fork")
892 Threaded_Fork(Filter* f1, Filter* f2, Filter* f3 = nullptr, Filter* f4 = nullptr);
893
894 /**
895 * Construct a Threaded_Fork from range of filters
896 * @param filter_arr the list of filters
897 * @param length how many filters
898 */
899 BOTAN_DEPRECATED("Deprecated, use plain Fork") Threaded_Fork(Filter* filter_arr[], size_t length);
900
901 ~Threaded_Fork() override;
902
903 Threaded_Fork(const Threaded_Fork& other) = delete;
904 Threaded_Fork(Threaded_Fork&& other) = delete;
905 Threaded_Fork& operator=(const Threaded_Fork& other) = delete;
906 Threaded_Fork& operator=(Threaded_Fork&& other) = delete;
907
908 private:
909 void set_next(Filter* f[], size_t n);
910 void send(const uint8_t in[], size_t length) override;
911 void thread_delegate_work(const uint8_t input[], size_t length);
912 void thread_entry(Filter* filter);
913
914 std::vector<std::shared_ptr<std::thread>> m_threads;
915 std::unique_ptr<struct Threaded_Fork_Data> m_thread_data;
916};
917#endif
918
919} // namespace Botan
920
921#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
#define BOTAN_FUTURE_EXPLICIT
Definition api.h:52
Base64_Decoder(Decoder_Checking checking=NONE)
Definition b64_filt.cpp:105
std::string name() const override
Definition filters.h:655
std::string name() const override
Definition filters.h:611
BOTAN_FUTURE_EXPLICIT Base64_Encoder(bool line_breaks=false, size_t line_length=72, bool trailing_newline=false)
Definition b64_filt.cpp:20
std::string name() const override
Definition filters.h:786
void write(const uint8_t[], size_t) override
Definition filters.h:779
virtual ~Buffered_Filter()=default
void write(const std::vector< uint8_t, Alloc > &in, size_t length)
Definition filters.h:57
size_t current_position() const
Definition filters.h:106
virtual void buffered_block(const uint8_t input[], size_t length)=0
Buffered_Filter(size_t block_size, size_t final_minimum)
Definition buf_filt.cpp:18
virtual void buffered_final(const uint8_t input[], size_t length)=0
size_t buffered_block_size() const
Definition filters.h:100
void write(const uint8_t in[], size_t length)
Definition buf_filt.cpp:34
void write(const uint8_t input[], size_t length) override
Definition filters.h:802
BOTAN_FUTURE_EXPLICIT Chain(Filter *f1=nullptr, Filter *f2=nullptr, Filter *f3=nullptr, Filter *f4=nullptr)
Definition basefilt.cpp:14
std::string name() const override
Definition filters.h:808
Cipher_Mode_Filter(std::unique_ptr< Cipher_Mode > t)
Definition filters.h:179
Cipher_Mode_Filter(Cipher_Mode *t)
static std::unique_ptr< Cipher_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
void set_port(size_t n)
Definition filter.h:169
Filter(const Filter &)=delete
virtual void send(const uint8_t in[], size_t length)
Definition filter.cpp:30
virtual std::string name() const =0
std::string name() const override
Definition filters.h:852
void set_port(size_t n)
Definition filters.h:846
void write(const uint8_t input[], size_t length) override
Definition filters.h:839
Fork(Filter *f1, Filter *f2, Filter *f3=nullptr, Filter *f4=nullptr)
Definition basefilt.cpp:48
Hex_Decoder(Decoder_Checking checking=NONE)
Definition hex_filt.cpp:99
std::string name() const override
Definition filters.h:745
std::string name() const override
Definition filters.h:698
Hex_Encoder(Case the_case)
Definition hex_filt.cpp:33
virtual void set_key(const SymmetricKey &key)=0
bool valid_keylength(size_t length) const
Definition filters.h:148
virtual void set_iv(const InitializationVector &iv)
Definition filters.h:137
virtual bool valid_iv_length(size_t length) const
Definition filters.h:160
virtual Key_Length_Specification key_spec() const =0
size_t length() const
Definition symkey.h:28
bool empty() const
Definition symkey.h:40
OctetString SymmetricKey
Definition symkey.h:153
Decoder_Checking
Definition filter.h:193
@ NONE
Definition filter.h:193
OctetString InitializationVector
Definition symkey.h:158
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
Keyed_Filter * get_cipher(std::string_view algo_spec, Cipher_Dir direction)
Definition filters.h:238