Botan 3.0.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/secmem.h>
13#include <botan/data_snk.h>
14#include <botan/pipe.h>
15#include <botan/symkey.h>
16#include <botan/cipher_mode.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*/
41 {
42 public:
43 /**
44 * Write bytes into the buffered filter, which will them emit them
45 * in calls to buffered_block in the subclass
46 * @param in the input bytes
47 * @param length of in in bytes
48 */
49 void write(const uint8_t in[], size_t length);
50
51 template<typename Alloc>
52 void write(const std::vector<uint8_t, Alloc>& in, size_t length)
53 {
54 write(in.data(), length);
55 }
56
57 /**
58 * Finish a message, emitting to buffered_block and buffered_final
59 * Will throw an exception if less than final_minimum bytes were
60 * written into the filter.
61 */
62 void end_msg();
63
64 /**
65 * Initialize a Buffered_Filter
66 * @param block_size the function buffered_block will be called
67 * with inputs which are a multiple of this size
68 * @param final_minimum the function buffered_final will be called
69 * with at least this many bytes.
70 */
71 Buffered_Filter(size_t block_size, size_t final_minimum);
72
73 virtual ~Buffered_Filter() = default;
74 protected:
75 /**
76 * The block processor, implemented by subclasses
77 * @param input some input bytes
78 * @param length the size of input, guaranteed to be a multiple
79 * of block_size
80 */
81 virtual void buffered_block(const uint8_t input[], size_t length) = 0;
82
83 /**
84 * The final block, implemented by subclasses
85 * @param input some input bytes
86 * @param length the size of input, guaranteed to be at least
87 * final_minimum bytes
88 */
89 virtual void buffered_final(const uint8_t input[], size_t length) = 0;
90
91 /**
92 * @return block size of inputs
93 */
94 size_t buffered_block_size() const { return m_main_block_mod; }
95
96 /**
97 * @return current position in the buffer
98 */
99 size_t current_position() const { return m_buffer_pos; }
100
101 /**
102 * Reset the buffer position
103 */
104 void buffer_reset() { m_buffer_pos = 0; }
105 private:
106 size_t m_main_block_mod, m_final_minimum;
107
108 secure_vector<uint8_t> m_buffer;
109 size_t m_buffer_pos;
110 };
111
112/**
113* This class represents keyed filters, i.e. filters that have to be
114* fed with a key in order to function.
115*/
117 {
118 public:
119 /**
120 * Set the key of this filter
121 * @param key the key to use
122 */
123 virtual void set_key(const SymmetricKey& key) = 0;
124
125 /**
126 * Set the initialization vector of this filter. Note: you should
127 * call set_iv() only after you have called set_key()
128 * @param iv the initialization vector to use
129 */
130 virtual void set_iv(const InitializationVector& iv)
131 {
132 if(iv.length() != 0)
133 throw Invalid_IV_Length(name(), iv.length());
134 }
135
136 /**
137 * Check whether a key length is valid for this filter
138 * @param length the key length to be checked for validity
139 * @return true if the key length is valid, false otherwise
140 */
141 bool valid_keylength(size_t length) const
142 {
143 return key_spec().valid_keylength(length);
144 }
145
146 /**
147 * @return object describing limits on key size
148 */
150
151 /**
152 * Check whether an IV length is valid for this filter
153 * @param length the IV length to be checked for validity
154 * @return true if the IV length is valid, false otherwise
155 */
156 virtual bool valid_iv_length(size_t length) const
157 { return (length == 0); }
158 };
159
160/**
161* Filter interface for cipher modes
162*/
164 private Buffered_Filter
165 {
166 public:
167 explicit Cipher_Mode_Filter(Cipher_Mode* t);
168
169 explicit Cipher_Mode_Filter(std::unique_ptr<Cipher_Mode> t) :
170 Cipher_Mode_Filter(t.release()) {}
171
172 void set_iv(const InitializationVector& iv) override;
173
174 void set_key(const SymmetricKey& key) override;
175
176 Key_Length_Specification key_spec() const override;
177
178 bool valid_iv_length(size_t length) const override;
179
180 std::string name() const override;
181
182 private:
183 void write(const uint8_t input[], size_t input_length) override;
184 void start_msg() override;
185 void end_msg() override;
186
187 void buffered_block(const uint8_t input[], size_t input_length) override;
188 void buffered_final(const uint8_t input[], size_t input_length) override;
189
190 std::unique_ptr<Cipher_Mode> m_mode;
191 std::vector<uint8_t> m_nonce;
192 secure_vector<uint8_t> m_buffer;
193 };
194
195/*
196* Get a cipher object
197*/
198
199/**
200* Factory method for general symmetric cipher filters. No key will be
201* set in the filter.
202*
203* @param algo_spec the name of the desired cipher
204* @param direction determines whether the filter will be an encrypting or
205* decrypting filter
206* @return pointer to the encryption or decryption filter
207*/
208inline Keyed_Filter* get_cipher(std::string_view algo_spec,
209 Cipher_Dir direction)
210 {
211 auto c = Cipher_Mode::create_or_throw(algo_spec, direction);
212 return new Cipher_Mode_Filter(c.release());
213 }
214
215/**
216* Factory method for general symmetric cipher filters.
217* @param algo_spec the name of the desired cipher
218* @param key the key to be used for encryption/decryption performed by
219* the filter
220* @param direction determines whether the filter will be an encrypting
221* or decrypting filter
222* @return pointer to the encryption or decryption filter
223*/
224inline Keyed_Filter* get_cipher(std::string_view algo_spec,
225 const SymmetricKey& key,
226 Cipher_Dir direction)
227 {
228 Keyed_Filter* cipher = get_cipher(algo_spec, direction);
229 cipher->set_key(key);
230 return cipher;
231 }
232
233/**
234* Factory method for general symmetric cipher filters.
235* @param algo_spec the name of the desired cipher
236* @param key the key to be used for encryption/decryption performed by
237* the filter
238* @param iv the initialization vector to be used
239* @param direction determines whether the filter will be an encrypting
240* or decrypting filter
241* @return pointer to newly allocated encryption or decryption filter
242*/
243inline Keyed_Filter* get_cipher(std::string_view algo_spec,
244 const SymmetricKey& key,
245 const InitializationVector& iv,
246 Cipher_Dir direction)
247 {
248 Keyed_Filter* cipher = get_cipher(algo_spec, key, direction);
249 if(iv.length())
250 cipher->set_iv(iv);
251 return cipher;
252 }
253
254#if defined(BOTAN_HAS_STREAM_CIPHER)
255
256/**
257* Stream Cipher Filter
258*/
259class BOTAN_PUBLIC_API(2,0) StreamCipher_Filter final : public Keyed_Filter
260 {
261 public:
262
263 std::string name() const override { return m_cipher->name(); }
264
265 /**
266 * Write input data
267 * @param input data
268 * @param input_len length of input in bytes
269 */
270 void write(const uint8_t input[], size_t input_len) override;
271
272 bool valid_iv_length(size_t iv_len) const override
273 { return m_cipher->valid_iv_length(iv_len); }
274
275 /**
276 * Set the initialization vector for this filter.
277 * @param iv the initialization vector to set
278 */
279 void set_iv(const InitializationVector& iv) override
280 {
281 m_cipher->set_iv(iv.begin(), iv.length());
282 }
283
284 /**
285 * Set the key of this filter.
286 * @param key the key to set
287 */
288 void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); }
289
290 Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); }
291
292 /**
293 * Construct a stream cipher filter.
294 * @param cipher a cipher object to use
295 */
296 explicit StreamCipher_Filter(StreamCipher* cipher);
297
298 /**
299 * Construct a stream cipher filter.
300 * @param cipher a cipher object to use
301 * @param key the key to use inside this filter
302 */
303 StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key);
304
305 /**
306 * Construct a stream cipher filter.
307 * @param cipher the name of the desired cipher
308 */
309 explicit StreamCipher_Filter(std::string_view cipher);
310
311 /**
312 * Construct a stream cipher filter.
313 * @param cipher the name of the desired cipher
314 * @param key the key to use inside this filter
315 */
316 StreamCipher_Filter(std::string_view cipher, const SymmetricKey& key);
317 private:
318 std::unique_ptr<StreamCipher> m_cipher;
319 secure_vector<uint8_t> m_buffer;
320 };
321#endif
322
323#if defined(BOTAN_HAS_HASH)
324
325/**
326* Hash Filter.
327*/
328class BOTAN_PUBLIC_API(2,0) Hash_Filter final : public Filter
329 {
330 public:
331 void write(const uint8_t input[], size_t len) override { m_hash->update(input, len); }
332 void end_msg() override;
333
334 std::string name() const override { return m_hash->name(); }
335
336 /**
337 * Construct a hash filter.
338 * @param hash the hash function to use
339 * @param len the output length of this filter. Leave the default
340 * value 0 if you want to use the full output of the hashfunction
341 * hash. Otherwise, specify a smaller value here so that the
342 * output of the hash algorithm will be cut off.
343 */
344 Hash_Filter(HashFunction* hash, size_t len = 0) :
345 m_hash(hash), m_out_len(len) {}
346
347 /**
348 * Construct a hash filter.
349 * @param request the name of the hash algorithm to use
350 * @param len the output length of this filter. Leave the default
351 * value 0 if you want to use the full output of the hashfunction
352 * hash. Otherwise, specify a smaller value here so that the
353 * output of the hash algorithm will be cut off.
354 */
355 Hash_Filter(std::string_view request, size_t len = 0);
356
357 private:
358 std::unique_ptr<HashFunction> m_hash;
359 const size_t m_out_len;
360 };
361#endif
362
363#if defined(BOTAN_HAS_MAC)
364
365/**
366* MessageAuthenticationCode Filter.
367*/
368class BOTAN_PUBLIC_API(2,0) MAC_Filter final : public Keyed_Filter
369 {
370 public:
371 void write(const uint8_t input[], size_t len) override { m_mac->update(input, len); }
372 void end_msg() override;
373
374 std::string name() const override { return m_mac->name(); }
375
376 /**
377 * Set the key of this filter.
378 * @param key the key to set
379 */
380 void set_key(const SymmetricKey& key) override { m_mac->set_key(key); }
381
382 Key_Length_Specification key_spec() const override { return m_mac->key_spec(); }
383
384 /**
385 * Construct a MAC filter. The MAC key will be left empty.
386 * @param mac the MAC to use
387 * @param out_len the output length of this filter. Leave the default
388 * value 0 if you want to use the full output of the
389 * MAC. Otherwise, specify a smaller value here so that the
390 * output of the MAC will be cut off.
391 */
392 MAC_Filter(MessageAuthenticationCode* mac,
393 size_t out_len = 0) :
394 m_mac(mac),
395 m_out_len(out_len)
396 {
397 }
398
399 /**
400 * Construct a MAC filter.
401 * @param mac the MAC to use
402 * @param key the MAC key to use
403 * @param out_len the output length of this filter. Leave the default
404 * value 0 if you want to use the full output of the
405 * MAC. Otherwise, specify a smaller value here so that the
406 * output of the MAC will be cut off.
407 */
408 MAC_Filter(MessageAuthenticationCode* mac,
409 const SymmetricKey& key,
410 size_t out_len = 0) :
411 m_mac(mac),
412 m_out_len(out_len)
413 {
414 m_mac->set_key(key);
415 }
416
417 /**
418 * Construct a MAC filter. The MAC key will be left empty.
419 * @param mac the name of the MAC to use
420 * @param len the output length of this filter. Leave the default
421 * value 0 if you want to use the full output of the
422 * MAC. Otherwise, specify a smaller value here so that the
423 * output of the MAC will be cut off.
424 */
425 MAC_Filter(std::string_view mac, size_t len = 0);
426
427 /**
428 * Construct a MAC filter.
429 * @param mac the name of the MAC to use
430 * @param key the MAC key to use
431 * @param len the output length of this filter. Leave the default
432 * value 0 if you want to use the full output of the
433 * MAC. Otherwise, specify a smaller value here so that the
434 * output of the MAC will be cut off.
435 */
436 MAC_Filter(std::string_view mac, const SymmetricKey& key,
437 size_t len = 0);
438 private:
439 std::unique_ptr<MessageAuthenticationCode> m_mac;
440 const size_t m_out_len;
441 };
442#endif
443
444#if defined(BOTAN_HAS_COMPRESSION)
445
446class Compression_Algorithm;
447class Decompression_Algorithm;
448
449/**
450* Filter interface for compression
451*/
452class BOTAN_PUBLIC_API(2,0) Compression_Filter final : public Filter
453 {
454 public:
455 void start_msg() override;
456 void write(const uint8_t input[], size_t input_length) override;
457 void end_msg() override;
458
459 void flush();
460
461 std::string name() const override;
462
463 Compression_Filter(std::string_view type,
464 size_t compression_level,
465 size_t buffer_size = 4096);
466
467 ~Compression_Filter();
468 private:
469 std::unique_ptr<Compression_Algorithm> m_comp;
470 size_t m_buffersize, m_level;
471 secure_vector<uint8_t> m_buffer;
472 };
473
474/**
475* Filter interface for decompression
476*/
477class BOTAN_PUBLIC_API(2,0) Decompression_Filter final : public Filter
478 {
479 public:
480 void start_msg() override;
481 void write(const uint8_t input[], size_t input_length) override;
482 void end_msg() override;
483
484 std::string name() const override;
485
486 Decompression_Filter(std::string_view type,
487 size_t buffer_size = 4096);
488
489 ~Decompression_Filter();
490 private:
491 std::unique_ptr<Decompression_Algorithm> m_comp;
492 std::size_t m_buffersize;
493 secure_vector<uint8_t> m_buffer;
494 };
495
496#endif
497
498/**
499* This class represents a Base64 encoder.
500*/
502 {
503 public:
504 std::string name() const override { return "Base64_Encoder"; }
505
506 /**
507 * Input a part of a message to the encoder.
508 * @param input the message to input as a byte array
509 * @param length the length of the byte array input
510 */
511 void write(const uint8_t input[], size_t length) override;
512
513 /**
514 * Inform the Encoder that the current message shall be closed.
515 */
516 void end_msg() override;
517
518 /**
519 * Create a base64 encoder.
520 * @param line_breaks whether to use line breaks in the output
521 * @param line_length the length of the lines of the output
522 * @param trailing_newline whether to use a trailing newline
523 */
524 Base64_Encoder(bool line_breaks = false, size_t line_length = 72,
525 bool trailing_newline = false);
526 private:
527 void encode_and_send(const uint8_t input[], size_t length,
528 bool final_inputs = false);
529 void do_output(const uint8_t output[], size_t length);
530
531 const size_t m_line_length;
532 const bool m_trailing_newline;
533 std::vector<uint8_t> m_in, m_out;
534 size_t m_position, m_out_position;
535 };
536
537/**
538* This object represents a Base64 decoder.
539*/
541 {
542 public:
543 std::string name() const override { return "Base64_Decoder"; }
544
545 /**
546 * Input a part of a message to the decoder.
547 * @param input the message to input as a byte array
548 * @param length the length of the byte array input
549 */
550 void write(const uint8_t input[], size_t length) override;
551
552 /**
553 * Finish up the current message
554 */
555 void end_msg() override;
556
557 /**
558 * Create a base64 decoder.
559 * @param checking the type of checking that shall be performed by
560 * the decoder
561 */
562 explicit Base64_Decoder(Decoder_Checking checking = NONE);
563 private:
564 const Decoder_Checking m_checking;
565 std::vector<uint8_t> m_in, m_out;
566 size_t m_position;
567 };
568
569/**
570* Converts arbitrary binary data to hex strings, optionally with
571* newlines inserted
572*/
574 {
575 public:
576 /**
577 * Whether to use uppercase or lowercase letters for the encoded string.
578 */
579 enum Case { Uppercase, Lowercase };
580
581 std::string name() const override { return "Hex_Encoder"; }
582
583 void write(const uint8_t in[], size_t length) override;
584 void end_msg() override;
585
586 /**
587 * Create a hex encoder.
588 * @param the_case the case to use in the encoded strings.
589 */
590 explicit Hex_Encoder(Case the_case);
591
592 /**
593 * Create a hex encoder.
594 * @param newlines should newlines be used
595 * @param line_length if newlines are used, how long are lines
596 * @param the_case the case to use in the encoded strings
597 */
598 Hex_Encoder(bool newlines = false,
599 size_t line_length = 72,
600 Case the_case = Uppercase);
601 private:
602 void encode_and_send(const uint8_t[], size_t);
603
604 const Case m_casing;
605 const size_t m_line_length;
606 std::vector<uint8_t> m_in, m_out;
607 size_t m_position, m_counter;
608 };
609
610/**
611* Converts hex strings to bytes
612*/
614 {
615 public:
616 std::string name() const override { return "Hex_Decoder"; }
617
618 void write(const uint8_t[], size_t) override;
619 void end_msg() override;
620
621 /**
622 * Construct a Hex Decoder using the specified
623 * character checking.
624 * @param checking the checking to use during decoding.
625 */
626 explicit Hex_Decoder(Decoder_Checking checking = NONE);
627 private:
628 const Decoder_Checking m_checking;
629 std::vector<uint8_t> m_in, m_out;
630 size_t m_position;
631 };
632
633/**
634* BitBucket is a filter which simply discards all inputs
635*/
637 {
638 public:
639 void write(const uint8_t[], size_t) override { /* discard */ }
640
641 std::string name() const override { return "BitBucket"; }
642 };
643
644/**
645* This class represents Filter chains. A Filter chain is an ordered
646* concatenation of Filters, the input to a Chain sequentially passes
647* through all the Filters contained in the Chain.
648*/
649
651 {
652 public:
653 void write(const uint8_t input[], size_t length) override { send(input, length); }
654
655 std::string name() const override { return "Chain"; }
656
657 /**
658 * Construct a chain of up to four filters. The filters are set
659 * up in the same order as the arguments.
660 */
661 Chain(Filter* = nullptr, Filter* = nullptr,
662 Filter* = nullptr, Filter* = nullptr);
663
664 /**
665 * Construct a chain from range of filters
666 * @param filter_arr the list of filters
667 * @param length how many filters
668 */
669 Chain(Filter* filter_arr[], size_t length);
670 };
671
672/**
673* This class represents a fork filter, whose purpose is to fork the
674* flow of data. It causes an input message to result in n messages at
675* the end of the filter, where n is the number of forks.
676*/
678 {
679 public:
680 void write(const uint8_t input[], size_t length) override { send(input, length); }
681 void set_port(size_t n) { Fanout_Filter::set_port(n); }
682
683 std::string name() const override { return "Fork"; }
684
685 /**
686 * Construct a Fork filter with up to four forks.
687 */
688 Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr);
689
690 /**
691 * Construct a Fork from range of filters
692 * @param filter_arr the list of filters
693 * @param length how many filters
694 */
695 Fork(Filter* filter_arr[], size_t length);
696 };
697
698#if defined(BOTAN_HAS_THREAD_UTILS)
699
700/**
701* This class is a threaded version of the Fork filter. While this uses
702* threads, the class itself is NOT thread-safe. This is meant as a drop-
703* in replacement for Fork where performance gains are possible.
704*/
705class BOTAN_PUBLIC_API(2,0) Threaded_Fork final : public Fork
706 {
707 public:
708 std::string name() const override;
709
710 /**
711 * Construct a Threaded_Fork filter with up to four forks.
712 */
713 Threaded_Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr);
714
715 /**
716 * Construct a Threaded_Fork from range of filters
717 * @param filter_arr the list of filters
718 * @param length how many filters
719 */
720 Threaded_Fork(Filter* filter_arr[], size_t length);
721
722 ~Threaded_Fork();
723
724 private:
725 void set_next(Filter* f[], size_t n);
726 void send(const uint8_t in[], size_t length) override;
727 void thread_delegate_work(const uint8_t input[], size_t length);
728 void thread_entry(Filter* filter);
729
730 std::vector<std::shared_ptr<std::thread>> m_threads;
731 std::unique_ptr<struct Threaded_Fork_Data> m_thread_data;
732 };
733#endif
734
735}
736
737#endif
std::string name() const override
Definition: filters.h:543
std::string name() const override
Definition: filters.h:504
std::string name() const override
Definition: filters.h:641
void write(const uint8_t[], size_t) override
Definition: filters.h:639
virtual ~Buffered_Filter()=default
void write(const std::vector< uint8_t, Alloc > &in, size_t length)
Definition: filters.h:52
size_t current_position() const
Definition: filters.h:99
virtual void buffered_block(const uint8_t input[], size_t length)=0
virtual void buffered_final(const uint8_t input[], size_t length)=0
size_t buffered_block_size() const
Definition: filters.h:94
void write(const uint8_t input[], size_t length) override
Definition: filters.h:653
std::string name() const override
Definition: filters.h:655
Cipher_Mode_Filter(std::unique_ptr< Cipher_Mode > t)
Definition: filters.h:169
static std::unique_ptr< Cipher_Mode > create_or_throw(std::string_view algo, Cipher_Dir direction, std::string_view provider="")
Definition: cipher_mode.cpp:40
std::string name() const override
Definition: filters.h:683
void set_port(size_t n)
Definition: filters.h:681
void write(const uint8_t input[], size_t length) override
Definition: filters.h:680
std::string name() const override
Definition: filters.h:616
std::string name() const override
Definition: filters.h:581
virtual void set_key(const SymmetricKey &key)=0
bool valid_keylength(size_t length) const
Definition: filters.h:141
virtual void set_iv(const InitializationVector &iv)
Definition: filters.h:130
virtual bool valid_iv_length(size_t length) const
Definition: filters.h:156
virtual Key_Length_Specification key_spec() const =0
size_t length() const
Definition: symkey.h:28
std::string name
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: alg_id.cpp:12
Cipher_Dir
Definition: cipher_mode.h:26
Decoder_Checking
Definition: filter.h:166
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64
Keyed_Filter * get_cipher(std::string_view algo_spec, Cipher_Dir direction)
Definition: filters.h:208