Botan 2.19.1
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// deprecated aliases, will be removed in a future major release
198
199/*
200* Get a cipher object
201*/
202
203/**
204* Factory method for general symmetric cipher filters. No key will be
205* set in the filter.
206*
207* @param algo_spec the name of the desired cipher
208* @param direction determines whether the filter will be an encrypting or
209* decrypting filter
210* @return pointer to the encryption or decryption filter
211*/
212inline Keyed_Filter* get_cipher(const std::string& algo_spec,
213 Cipher_Dir direction)
214 {
215 std::unique_ptr<Cipher_Mode> c(Cipher_Mode::create_or_throw(algo_spec, direction));
216 return new Cipher_Mode_Filter(c.release());
217 }
218
219/**
220* Factory method for general symmetric cipher filters.
221* @param algo_spec the name of the desired cipher
222* @param key the key to be used for encryption/decryption performed by
223* the filter
224* @param direction determines whether the filter will be an encrypting
225* or decrypting filter
226* @return pointer to the encryption or decryption filter
227*/
228inline Keyed_Filter* get_cipher(const std::string& algo_spec,
229 const SymmetricKey& key,
230 Cipher_Dir direction)
231 {
232 Keyed_Filter* cipher = get_cipher(algo_spec, direction);
233 cipher->set_key(key);
234 return cipher;
235 }
236
237/**
238* Factory method for general symmetric cipher filters.
239* @param algo_spec the name of the desired cipher
240* @param key the key to be used for encryption/decryption performed by
241* the filter
242* @param iv the initialization vector to be used
243* @param direction determines whether the filter will be an encrypting
244* or decrypting filter
245* @return pointer to newly allocated encryption or decryption filter
246*/
247inline Keyed_Filter* get_cipher(const std::string& algo_spec,
248 const SymmetricKey& key,
249 const InitializationVector& iv,
250 Cipher_Dir direction)
251 {
252 Keyed_Filter* cipher = get_cipher(algo_spec, key, direction);
253 if(iv.length())
254 cipher->set_iv(iv);
255 return cipher;
256 }
257
258#if defined(BOTAN_HAS_STREAM_CIPHER)
259
260/**
261* Stream Cipher Filter
262*/
263class BOTAN_PUBLIC_API(2,0) StreamCipher_Filter final : public Keyed_Filter
264 {
265 public:
266
267 std::string name() const override { return m_cipher->name(); }
268
269 /**
270 * Write input data
271 * @param input data
272 * @param input_len length of input in bytes
273 */
274 void write(const uint8_t input[], size_t input_len) override;
275
276 bool valid_iv_length(size_t iv_len) const override
277 { return m_cipher->valid_iv_length(iv_len); }
278
279 /**
280 * Set the initialization vector for this filter.
281 * @param iv the initialization vector to set
282 */
283 void set_iv(const InitializationVector& iv) override
284 {
285 m_cipher->set_iv(iv.begin(), iv.length());
286 }
287
288 /**
289 * Set the key of this filter.
290 * @param key the key to set
291 */
292 void set_key(const SymmetricKey& key) override { m_cipher->set_key(key); }
293
294 Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); }
295
296 /**
297 * Construct a stream cipher filter.
298 * @param cipher a cipher object to use
299 */
300 explicit StreamCipher_Filter(StreamCipher* cipher);
301
302 /**
303 * Construct a stream cipher filter.
304 * @param cipher a cipher object to use
305 * @param key the key to use inside this filter
306 */
307 StreamCipher_Filter(StreamCipher* cipher, const SymmetricKey& key);
308
309 /**
310 * Construct a stream cipher filter.
311 * @param cipher the name of the desired cipher
312 */
313 explicit StreamCipher_Filter(const std::string& cipher);
314
315 /**
316 * Construct a stream cipher filter.
317 * @param cipher the name of the desired cipher
318 * @param key the key to use inside this filter
319 */
320 StreamCipher_Filter(const std::string& cipher, const SymmetricKey& key);
321 private:
322 secure_vector<uint8_t> m_buffer;
323 std::unique_ptr<StreamCipher> m_cipher;
324 };
325#endif
326
327#if defined(BOTAN_HAS_HASH)
328
329/**
330* Hash Filter.
331*/
332class BOTAN_PUBLIC_API(2,0) Hash_Filter final : public Filter
333 {
334 public:
335 void write(const uint8_t input[], size_t len) override { m_hash->update(input, len); }
336 void end_msg() override;
337
338 std::string name() const override { return m_hash->name(); }
339
340 /**
341 * Construct a hash filter.
342 * @param hash the hash function to use
343 * @param len the output length of this filter. Leave the default
344 * value 0 if you want to use the full output of the hashfunction
345 * hash. Otherwise, specify a smaller value here so that the
346 * output of the hash algorithm will be cut off.
347 */
348 Hash_Filter(HashFunction* hash, size_t len = 0) :
349 m_hash(hash), m_out_len(len) {}
350
351 /**
352 * Construct a hash filter.
353 * @param request the name of the hash algorithm to use
354 * @param len the output length of this filter. Leave the default
355 * value 0 if you want to use the full output of the hashfunction
356 * hash. Otherwise, specify a smaller value here so that the
357 * output of the hash algorithm will be cut off.
358 */
359 Hash_Filter(const std::string& request, size_t len = 0);
360
361 private:
362 std::unique_ptr<HashFunction> m_hash;
363 const size_t m_out_len;
364 };
365#endif
366
367#if defined(BOTAN_HAS_MAC)
368
369/**
370* MessageAuthenticationCode Filter.
371*/
372class BOTAN_PUBLIC_API(2,0) MAC_Filter final : public Keyed_Filter
373 {
374 public:
375 void write(const uint8_t input[], size_t len) override { m_mac->update(input, len); }
376 void end_msg() override;
377
378 std::string name() const override { return m_mac->name(); }
379
380 /**
381 * Set the key of this filter.
382 * @param key the key to set
383 */
384 void set_key(const SymmetricKey& key) override { m_mac->set_key(key); }
385
386 Key_Length_Specification key_spec() const override { return m_mac->key_spec(); }
387
388 /**
389 * Construct a MAC filter. The MAC key will be left empty.
390 * @param mac the MAC to use
391 * @param out_len the output length of this filter. Leave the default
392 * value 0 if you want to use the full output of the
393 * MAC. Otherwise, specify a smaller value here so that the
394 * output of the MAC will be cut off.
395 */
396 MAC_Filter(MessageAuthenticationCode* mac,
397 size_t out_len = 0) :
398 m_mac(mac),
399 m_out_len(out_len)
400 {
401 }
402
403 /**
404 * Construct a MAC filter.
405 * @param mac the MAC to use
406 * @param key the MAC key to use
407 * @param out_len the output length of this filter. Leave the default
408 * value 0 if you want to use the full output of the
409 * MAC. Otherwise, specify a smaller value here so that the
410 * output of the MAC will be cut off.
411 */
412 MAC_Filter(MessageAuthenticationCode* mac,
413 const SymmetricKey& key,
414 size_t out_len = 0) :
415 m_mac(mac),
416 m_out_len(out_len)
417 {
418 m_mac->set_key(key);
419 }
420
421 /**
422 * Construct a MAC filter. The MAC key will be left empty.
423 * @param mac the name of the MAC to use
424 * @param len the output length of this filter. Leave the default
425 * value 0 if you want to use the full output of the
426 * MAC. Otherwise, specify a smaller value here so that the
427 * output of the MAC will be cut off.
428 */
429 MAC_Filter(const std::string& mac, size_t len = 0);
430
431 /**
432 * Construct a MAC filter.
433 * @param mac the name of the MAC to use
434 * @param key the MAC key to use
435 * @param len the output length of this filter. Leave the default
436 * value 0 if you want to use the full output of the
437 * MAC. Otherwise, specify a smaller value here so that the
438 * output of the MAC will be cut off.
439 */
440 MAC_Filter(const std::string& mac, const SymmetricKey& key,
441 size_t len = 0);
442 private:
443 std::unique_ptr<MessageAuthenticationCode> m_mac;
444 const size_t m_out_len;
445 };
446#endif
447
448#if defined(BOTAN_HAS_COMPRESSION)
449
450class Compression_Algorithm;
451class Decompression_Algorithm;
452
453/**
454* Filter interface for compression
455*/
456class BOTAN_PUBLIC_API(2,0) Compression_Filter final : public Filter
457 {
458 public:
459 void start_msg() override;
460 void write(const uint8_t input[], size_t input_length) override;
461 void end_msg() override;
462
463 void flush();
464
465 std::string name() const override;
466
467 Compression_Filter(const std::string& type,
468 size_t compression_level,
469 size_t buffer_size = 4096);
470
471 ~Compression_Filter();
472 private:
473 std::unique_ptr<Compression_Algorithm> m_comp;
474 size_t m_buffersize, m_level;
475 secure_vector<uint8_t> m_buffer;
476 };
477
478/**
479* Filter interface for decompression
480*/
481class BOTAN_PUBLIC_API(2,0) Decompression_Filter final : public Filter
482 {
483 public:
484 void start_msg() override;
485 void write(const uint8_t input[], size_t input_length) override;
486 void end_msg() override;
487
488 std::string name() const override;
489
490 Decompression_Filter(const std::string& type,
491 size_t buffer_size = 4096);
492
493 ~Decompression_Filter();
494 private:
495 std::unique_ptr<Decompression_Algorithm> m_comp;
496 std::size_t m_buffersize;
497 secure_vector<uint8_t> m_buffer;
498 };
499
500#endif
501
502/**
503* This class represents a Base64 encoder.
504*/
506 {
507 public:
508 std::string name() const override { return "Base64_Encoder"; }
509
510 /**
511 * Input a part of a message to the encoder.
512 * @param input the message to input as a byte array
513 * @param length the length of the byte array input
514 */
515 void write(const uint8_t input[], size_t length) override;
516
517 /**
518 * Inform the Encoder that the current message shall be closed.
519 */
520 void end_msg() override;
521
522 /**
523 * Create a base64 encoder.
524 * @param breaks whether to use line breaks in the output
525 * @param length the length of the lines of the output
526 * @param t_n whether to use a trailing newline
527 */
528 Base64_Encoder(bool breaks = false, size_t length = 72,
529 bool t_n = false);
530 private:
531 void encode_and_send(const uint8_t input[], size_t length,
532 bool final_inputs = false);
533 void do_output(const uint8_t output[], size_t length);
534
535 const size_t m_line_length;
536 const bool m_trailing_newline;
537 std::vector<uint8_t> m_in, m_out;
538 size_t m_position, m_out_position;
539 };
540
541/**
542* This object represents a Base64 decoder.
543*/
545 {
546 public:
547 std::string name() const override { return "Base64_Decoder"; }
548
549 /**
550 * Input a part of a message to the decoder.
551 * @param input the message to input as a byte array
552 * @param length the length of the byte array input
553 */
554 void write(const uint8_t input[], size_t length) override;
555
556 /**
557 * Finish up the current message
558 */
559 void end_msg() override;
560
561 /**
562 * Create a base64 decoder.
563 * @param checking the type of checking that shall be performed by
564 * the decoder
565 */
566 explicit Base64_Decoder(Decoder_Checking checking = NONE);
567 private:
568 const Decoder_Checking m_checking;
569 std::vector<uint8_t> m_in, m_out;
570 size_t m_position;
571 };
572
573/**
574* Converts arbitrary binary data to hex strings, optionally with
575* newlines inserted
576*/
578 {
579 public:
580 /**
581 * Whether to use uppercase or lowercase letters for the encoded string.
582 */
583 enum Case { Uppercase, Lowercase };
584
585 std::string name() const override { return "Hex_Encoder"; }
586
587 void write(const uint8_t in[], size_t length) override;
588 void end_msg() override;
589
590 /**
591 * Create a hex encoder.
592 * @param the_case the case to use in the encoded strings.
593 */
594 explicit Hex_Encoder(Case the_case);
595
596 /**
597 * Create a hex encoder.
598 * @param newlines should newlines be used
599 * @param line_length if newlines are used, how long are lines
600 * @param the_case the case to use in the encoded strings
601 */
602 Hex_Encoder(bool newlines = false,
603 size_t line_length = 72,
604 Case the_case = Uppercase);
605 private:
606 void encode_and_send(const uint8_t[], size_t);
607
608 const Case m_casing;
609 const size_t m_line_length;
610 std::vector<uint8_t> m_in, m_out;
611 size_t m_position, m_counter;
612 };
613
614/**
615* Converts hex strings to bytes
616*/
618 {
619 public:
620 std::string name() const override { return "Hex_Decoder"; }
621
622 void write(const uint8_t[], size_t) override;
623 void end_msg() override;
624
625 /**
626 * Construct a Hex Decoder using the specified
627 * character checking.
628 * @param checking the checking to use during decoding.
629 */
630 explicit Hex_Decoder(Decoder_Checking checking = NONE);
631 private:
632 const Decoder_Checking m_checking;
633 std::vector<uint8_t> m_in, m_out;
634 size_t m_position;
635 };
636
637/**
638* BitBucket is a filter which simply discards all inputs
639*/
641 {
642 public:
643 void write(const uint8_t[], size_t) override { /* discard */ }
644
645 std::string name() const override { return "BitBucket"; }
646 };
647
648/**
649* This class represents Filter chains. A Filter chain is an ordered
650* concatenation of Filters, the input to a Chain sequentially passes
651* through all the Filters contained in the Chain.
652*/
653
655 {
656 public:
657 void write(const uint8_t input[], size_t length) override { send(input, length); }
658
659 std::string name() const override { return "Chain"; }
660
661 /**
662 * Construct a chain of up to four filters. The filters are set
663 * up in the same order as the arguments.
664 */
665 Chain(Filter* = nullptr, Filter* = nullptr,
666 Filter* = nullptr, Filter* = nullptr);
667
668 /**
669 * Construct a chain from range of filters
670 * @param filter_arr the list of filters
671 * @param length how many filters
672 */
673 Chain(Filter* filter_arr[], size_t length);
674 };
675
676/**
677* This class represents a fork filter, whose purpose is to fork the
678* flow of data. It causes an input message to result in n messages at
679* the end of the filter, where n is the number of forks.
680*/
682 {
683 public:
684 void write(const uint8_t input[], size_t length) override { send(input, length); }
685 void set_port(size_t n) { Fanout_Filter::set_port(n); }
686
687 std::string name() const override { return "Fork"; }
688
689 /**
690 * Construct a Fork filter with up to four forks.
691 */
692 Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr);
693
694 /**
695 * Construct a Fork from range of filters
696 * @param filter_arr the list of filters
697 * @param length how many filters
698 */
699 Fork(Filter* filter_arr[], size_t length);
700 };
701
702#if defined(BOTAN_HAS_THREAD_UTILS)
703
704/**
705* This class is a threaded version of the Fork filter. While this uses
706* threads, the class itself is NOT thread-safe. This is meant as a drop-
707* in replacement for Fork where performance gains are possible.
708*/
709class BOTAN_PUBLIC_API(2,0) Threaded_Fork final : public Fork
710 {
711 public:
712 std::string name() const override;
713
714 /**
715 * Construct a Threaded_Fork filter with up to four forks.
716 */
717 Threaded_Fork(Filter*, Filter*, Filter* = nullptr, Filter* = nullptr);
718
719 /**
720 * Construct a Threaded_Fork from range of filters
721 * @param filter_arr the list of filters
722 * @param length how many filters
723 */
724 Threaded_Fork(Filter* filter_arr[], size_t length);
725
726 ~Threaded_Fork();
727
728 private:
729 void set_next(Filter* f[], size_t n);
730 void send(const uint8_t in[], size_t length) override;
731 void thread_delegate_work(const uint8_t input[], size_t length);
732 void thread_entry(Filter* filter);
733
734 std::vector<std::shared_ptr<std::thread>> m_threads;
735 std::unique_ptr<struct Threaded_Fork_Data> m_thread_data;
736 };
737#endif
738
739}
740
741#endif
std::string name() const override
Definition: filters.h:547
std::string name() const override
Definition: filters.h:508
std::string name() const override
Definition: filters.h:645
void write(const uint8_t[], size_t) override
Definition: filters.h:643
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:657
std::string name() const override
Definition: filters.h:659
Cipher_Mode_Filter(std::unique_ptr< Cipher_Mode > t)
Definition: filters.h:169
static std::unique_ptr< Cipher_Mode > create_or_throw(const std::string &algo, Cipher_Dir direction, const std::string &provider="")
Definition: cipher_mode.cpp:44
void set_port(size_t n)
Definition: filter.h:152
std::string name() const override
Definition: filters.h:687
void set_port(size_t n)
Definition: filters.h:685
void write(const uint8_t input[], size_t length) override
Definition: filters.h:684
std::string name() const override
Definition: filters.h:620
std::string name() const override
Definition: filters.h:585
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:25
std::string name
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
Definition: alg_id.cpp:13
OctetString InitializationVector
Definition: symkey.h:146
Transform_Filter Transformation_Filter
Definition: filters.h:197
OctetString SymmetricKey
Definition: symkey.h:141
Cipher_Dir
Definition: cipher_mode.h:23
Cipher_Mode_Filter Transform_Filter
Definition: filters.h:196
Decoder_Checking
Definition: filter.h:171
@ NONE
Definition: filter.h:171
Keyed_Filter * get_cipher(const std::string &algo_spec, Cipher_Dir direction)
Definition: filters.h:212
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
MechanismType hash
MechanismType type